Вопрос № 181589: Здравствуйте, уважаемые эксперты! Прошу решить задачу:Ввести число 95347. Вычесть из него число 27358, умножить на 10, сложить с числом 11100, разделить на 5. Вывести полученный результат.( среда, ассемблер 16 битный под DOS , tasm и tlink , использо...
Вопрос № 181589:
Здравствуйте, уважаемые эксперты! Прошу решить задачу:Ввести число 95347. Вычесть из него число 27358, умножить на 10, сложить с числом 11100, разделить на 5. Вывести полученный результат.( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small). Большая просьба написать комнтарий к каждой строчке, а то я ничего не понимаю в асемблере.
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Артем Воробьев! А вот и программа, "с пылу, с жару" Задание предусматривает умножение/деление, когда результат не помещается в слово Надо использовать двойные слова. Это раз. Второе: задание так построено, что обычные mul/div не работают! Будет переполнение! Т.о. возникла необходимость в написании собственных подпрограмм умножения/деления двойного слова на слово. При этом предполагаем, что результат умножения/сложения
не выходит за пределы двойного слова. PS Число 95347 вводим с клавиатуры...
Код:
;Ввести число 95347. ;Вычесть из него число 27358, ;умножить на 1
0, ;сложить с числом 11100, ;разделить на 5. ;Вывести полученный результат.
.186 ;чтобы можно было использовать push <число> .model small .code start: mov ax, @data mov ds, ax mov es, ax ;пусть es=ds=data
lea dx, sNum mov ah, 9 int 21h ;ждем число N
mov bNum, 80 ;задаем максимальное значение строки lea dx, bNum mov ah, 0ah int 21h ;вводим числовую строку
lea dx, sResult mov ah, 9 int 21h ;выведем сообщение
о результате
lea si, bBuf ;строка call stol ;преобразовываем в число dx:ax
sub ax, 27358 sbb dx, 0 ;dx:ax = dx:ax - 27358
push 10 push ax push dx call Mul_DW_W ;умножим на dx:ax на 10
Exit: lea dx, sPress ;выведем п
риглашение нажать на любую клавишу mov ah, 9 int 21h
mov ah, 0 ;ждем int 16h
mov ax, 4c00h int 21h ;выход в ДОС
;умножаем столбиком двойное слово на слово ;параметры: ;1 - старшее слово множимого mul_dw_hi equ word ptr [bp+4] ;2 - младшее слово множимого mul_dw_lo equ word ptr [bp+6] ;3 - множитель mul_w equ word ptr [bp+8] ;результат в dx:ax Mul_DW_W proc push bp mov bp, sp ;параметры будем адресовать через стек mov ax, mul_w ;ax
= множитель mul mul_dw_lo ;умножаем на младшее слово множителя push ax ;сохраняем младшее слово результата xchg dx, mul_dw_hi ;dx = ст слово множителя, mul_dw_hi = ст слово предыд умножения mov ax, mul_w ;ax = множитель mul dx ;умножаем на старшее слово множителя add ax, mul_dw_hi ;добавим ст слово предыд умножения mov dx, ax ;ст слово произведения pop ax ;мл слово произведения pop bp ret 6 ;уберем из стека 3 параметра M
ul_DW_W endp
;делим двойное слово на слово ;параметры: ;1 - ст слово делимого div_dw_hi equ word ptr [bp+4] ;2 - мл слово делимого div_dw_lo equ word ptr [bp+6] ;3 - делитель div_w equ word ptr [bp+8] ;результат: dx:ax - частное, bx - остаток Div_DW_W proc push bp mov bp, sp ;параметры будем адресовать через стек ;разделим старшее слово на делитель mov ax, div_dw_hi ;ax = ст слово делимого xor dx, dx ;dx = 0 div div_w ; push ax ;сохраним ст разряд
(ст слово) результата ;разделим мл слово на делитель ;при этом учитываем, что остаток от предыдущего деления есть ст слово для этого mov ax, div_dw_lo ;мл слово делимого div div_w ;ax = мл слово частного mov bx, dx ;bx = остаток pop dx ;dx = ст слово частного pop bp ret 6 ;уберем из стека 3 параметра Div_DW_W endp
;выводим двойное слово ;сначала сохраняем в стеке разряды (делением на 10), затем выводим в обратном порядке
;для деления используем Div_DW_W ;параметры: ;1 - ст слово num_hi equ [bp+4] ;1 - мл слово num_lo equ [bp+6] Print
Num proc push bp mov bp, sp ;параметры будем адресовать через стек mov ax, num_lo mov dx, num_hi ;число dx:ax xor cx, cx ;счетчик разрядов DivLoop: ;цикл преобразования в разряды push 10 push ax push dx call Div_DW_W ;dx:ax = dx:ax / 10 push bx ;сохраним в стеке остаток inc cx ;считаем test dx, dx ;проверим оба слова на 0 jnz DivLoop test ax, ax ;продолжаем, пока не дойдем до 0 jnz DivLoop PrLoop: ;цикл вывода в обратном порядке pop ax ;берем
число 0-9 из стека or al, '0' ;преобразовываем в символ '0'-'9' int 29h ;выводим loop PrLoop
pop bp ret 4 ;уберем из стека 2 параметра PrintNum endp
stol proc ;преобразование строки [si] в число DX:AX xor ax, ax ;будем стоить 32-битное число в dx:ax xor dx, dx xor cx, cx ;счетчик разрядов stol_next: mov bl, [si] ;очередной символ inc si cmp bl, 0dh ;конец стоки?
je stol_eol cmp bl, '0' jb stol_sep ;любая нецифра - разделитель cmp bl, '9' ja stol_sep
push 10 push ax push dx call Mul_DW_W ;dx:ax = dx:ax * 10 and bx, 0fh ;'0'-'9' -> 0-9 add ax, bx ;добавляем новый разряд adc dx, 0 ;учитываем перенос inc cx ;считаем jmp stol_next ;продолжаем stol_sep: ;встретили разделитель jcxz stol_next ;были только разделители - на продолжение ; иначе - конец числа и выходим stol_eol: ;
если числа нет и встретили 0dh - конец строки ret ;число возвращаем в dx:ax stol endp
.data sNum db 'Enter N: $' sResult db 0ah,'Result: $' sPress db 0dh,0ah,'Press any key$' ;буфер для ввода числовой строки (для функции 0ah) bNum db ? ;максимальный размер буфера bCount db ? ;реальный размер строки bBuf db 80 dup (?) ;сама строка
end start
----- Люби своего ближнего, как самого себя
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 24.12.2010, 16:54
Номер ответа: 265057 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 265057
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.