Вопрос № 178138: Доброго времени суток дорогие эксперты: Требуется с помощью TASM организовать решение задачи: Есть ли в данной строке слова, множества символов которых равны. Хар-ки: 1) процессор intel core 2 solo CPU U3500 2) window vista home pr...
Вопрос № 178214: Здравствуйте, помогите дописать программу на МАSМе, нужно вывести результат арифметического выражения : (a+b)/(c+d). моя программа выводит правильный результат если ответ положительный , если же он отрицательный то получается неправильный ответ , и е...
Вопрос № 178138:
Доброго времени суток дорогие эксперты: Требуется с помощью TASM организовать решение задачи: Есть ли в данной строке слова, множества символов которых равны.
Хар-ки: 1) процессор intel core 2 solo CPU U3500 2) window vista home premium 32х разрядная 3) Turbo Assembler Version 4.1 в папке asm находится файл TASM поэтому думаю он предпочтителен 4) вычисления производить в сопроцессоре
Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Юдин Евгений Сергеевич. Вот Вам программа. Думаю, комментарии в тексте помогут Вам разобраться
lea dx, sPrompt ;подсказка для ввода строки mov ah, 9 int 21h
lea dx, max ;вводим максимум 64 символа mov ah, 0ah int 21h
call strstr ;строим массив адресов слов call analysis ;анализируем, считаем и выводим
lea dx, sTotal ;выведем число найденных пар слов mov ah, 9 int 21h
mov ax, ecount ;количество ca
ll PrDec ;выведе десятичное число
lea dx, sPairs ;закончим сообщение mov ah, 9 int 21h
mov ah, 0 ;ждем нажатие на клавишу int 16h
mov ax, 4c00h ;выход в ДОС int 21h
;строим массив адресов слов strstr proc lea si, string-1 ;адрес введеной строки -1 (после inc si будет начало) lea bx, addrs ;здесь будем хранить адреса слов mov wcount, 0 ;число слов mov ah, 0 ;признак, что ждем, ah=0 - разделитель, ah=1 слово str_loop: ;цикл
по всем символам строки inc si ;на следующий символ mov al, [si] ;читаем очередной символ cmp al, 0dh ;конец строки? je str_ret ;на выход lea di, separ ;проверим, разделитель? mov cx, len_sep ;число возможных разделителей repne scasb ;ищем... jz str_sep ;нашли - разделитель cmp ah, 1 ;если во вводе слова, то на следующий символ je str_loop inc wcount ;получили начало нового слова, считаем mov ah, 1 ;призна
к слова mov [bx], si ;запоминаем начало слова lea bx, [bx+2] ;подготавливаем адрес для сохранения адреса след слова jmp str_loop ;на ввод очередного символа str_sep: ;встретили разделитель cmp ah, 0 ;если ожидали разделитель, je str_loop ; то уходим на ввод очередного символа mov ah, 0 ;признак разделителя mov byte ptr [si], 0 ;закрываем слово нулем jmp str_loop ;на ввод очередного символа str_ret: mov byte ptr [si], 0 ;на всякий случай, закрываем последнее
слово нулем ret ; (возможно, оно уже было закрыто) strstr endp
;сравниваем два слова [si] и [di] на совпадение множеств символов ;будем искать за два прохода: ;1) каждый символ в [si] ищем в [di] ;2) каждый символ в [di] ищем в [si] ;результат: ZF=1 - множества совпадают, ZF=0 - не совпадают Compare proc push cx si di ;сохраним регистры mov cx, 2 ;будем искать за два прохода cmp_loop_1: ;цикл по символам первого сло
ва lodsb ;очередной cmp al, 0 ;дошли до конца? je cmp_back ;на следующий проход или выход push di ;сохраним адрес второго слова cmp_loop_2: ;цикл по всем символам второго слова scasb ;сравниваем al и es:[di], di=di+1 je cmp_found ;равно? cmp byte ptr [di-1], 0 ;если не равно и не дошли до конца второй строки jne cmp_loop_2 ; то на следующий символ второй строки pop di ;не нашли! восстанавливаем di or al, 1 ;сбрасываем флаг ZF - признак несовпадения
множеств jmp cmp_ret ;на выход cmp_found: ;нашли... pop di ;восстанавливаем di jmp cmp_loop_1 ;на поиск следующего символа первого слова во втором слове cmp_back: ;очередной проход дал совпадение! pop si di ;поменяем местами адреса строка и пройдем еще раз! push si di ;загоним в стек для корректного выхода loop cmp_loop_1 ;на следующий проход или выход cmp_ret: ;сюда попадем при ZF=1 и множества равны! pop di si c
x ;восстановим регистры ret Compare endp
;выведем результат Print proc push si ;сохраним si cmp ecount, 0 ;вы
ведем заголовок только в самом начале! jne pr_1_loop lea dx, sWords ;заголовок mov ah, 9 int 21h pr_1_loop: ;выведем первое слово lodsb cmp al, 0 je Pr_space int 29h jmp pr_1_loop Pr_space: mov al, ' ' ;отделим пробелом int 29h mov si, di ;выведем второе слово pr_2_loop: lodsb cmp al, 0 je Pr_ret int 29h jmp pr_2_loop Pr_ret: mov al, 0dh ;перейдем на новую строку int 29h mov al, 0ah int 29h inc ecount ;посчитаем pop si ret Print endp
;проанализируем
строки analysis proc mov ecount, 0 ;счетчик равных пар mov cx, wcount ;счетчик слов jcxz an_ret ;для 0 нечего делать lea bx, addrs ;адрес массива адресов слов jmp an_next_1 ;на проверку количества первых слов an_loop_1: ;цикл первого слова mov si, [bx] ;адрес первого слова lea bx, [bx+2] ;на следующий адрес mov bp, bx ;сохраним как начало массив
а вторых слов push cx ;сохраним счетчик jmp an_next_2 ;на проверку количества вторых слов an_loop_2: ;цикл второго слова mov di, ds:[bp] ;адрес второго слова lea bp, [bp+2] ;на следующий адрес call Compare ;сравниваем! jnz an_next_2 ;если неравно, то на адрес следующего второго слова call Print ;равно - посчитаем и выведем на экран an_next_2: dec cx ;циклим, пока cx>=0 jge an_loop_2 pop cx ;восстановим счетчик аресов первого слова an_next_1: loop an_loop_1 ;циклим,
пока cx>0 an_ret: ;выходим ret analysis endp
;вывод десятичного числа из ax PrDec proc mov bx, 10 xor cx, cx pd_dig: ;цикл формирования цифр, xor dx, dx ; как остатков от деления на 10 div bx push dx inc cx or ax, ax jnz pd_dig pd_pr: ;цикл вывода цифр pop ax add al, '0' int 29h LOOP pd_pr ret PrDec endp
cseg ends
dseg segment para public 'data' separ db ' ,;:.',9 ;массив разделителей len_sep equ $-separ
sPrompt db 'Enter string: $' sWords db 0dh,0ah,'Founded words:',0dh,0ah,'$' sTotal db 0dh,0ah,'Total $' sPairs db ' words pair(s)',0dh,0ah db 'Press any key for exit$' max db 65 ;максимально возможная длина = 64 (+1 для 0dh) rcount db 0 ;реальная длина string db 65 dup (?) ;сама строка wcount dw 0 ;счетчик слов в
строке ecount dw 0 ;счетчик найденных совпадений множеств символов строк addrs label word ;адрес для хранения массива адресов строк dseg ends
end start ;конец программы
----- Удачи!
Ответ отправил: Лысков Игорь Витальевич, Модератор
Ответ отправлен: 05.05.2010, 15:41
Номер ответа: 261213 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru Абонент Skype: igorlyskov
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 261213
на номер 1151 (Россия) |
Еще номера »
Вопрос № 178214:
Здравствуйте, помогите дописать программу на МАSМе, нужно вывести результат арифметического выражения : (a+b)/(c+d). моя программа выводит правильный результат если ответ положительный , если же он отрицательный то получается неправильный ответ , и ещё отдельно нужно вывести остаток если не делится нацело...
Отправлен: 05.05.2010, 13:27
Вопрос задал: Faraon, Посетитель
Всего ответов: 1 Страница вопроса »
Отвечает Лысков Игорь Витальевич, Модератор :
Здравствуйте, Faraon. Ваша ошибка была в том, что формат "%d" подразумевает двойное слово! А не слово, как у Вас. Программы под Windows 32-битные! Для формата short надо было использовать "%hd". Кроме того, почему Вы не пользуетесь возможностями 32-битного процессора? Например, можно было сделать (под 32-битные регистры, но можно так и с 16-битными) так:
Код:
movsx ebx, d movsx eax, k add ebx, eax jz label1 movsx ecx, a movsx eax, b add eax, ecx cdq idiv ebx
И так далее... но это так, к слову...
Код:
.386 .model flat, stdcall
include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib
.data Lab_Caption db "Lab8!",0 Print_Mask db "%hd",0 ;у нас слово, а не двойное слово!!! Print_Mask2 db " %hd",0 Print_Mess DB "The result is: " Print_Buff db 16 dup (0) ;увеличим
буфер Chars_Number dd ?
a db 127 b db -27 k db 10 d db -16 rez dw 0 tail dw 0
.code main: call AllocConsole or EAX,EAX jz fail
push offset Lab_Caption call SetConsoleTitleA or EAX,EAX jz fail
sub dx,dx sub ax,ax mov al,d cbw mov bx,ax mov al,k cbw add bx,ax ;bx=c+d mov al,a cbw mov cx,ax mov al,b cbw add ax,cx ;ax=a+b cmp bx
,0 je label1 idiv bx cbw mov rez,ax ;лучше так, а не add mov tail,dx ;остаток
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.