Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты данной рассылки Номер выпуска: | 1410 | Дата выхода: | 29.12.2010, 17:00 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 222 / 69 | Вопросов / ответов: | 1 / 1 | Вопрос № 181589: Здравствуйте, уважаемые эксперты! Прошу решить задачу:Ввести число 95347. Вычесть из него число 27358, умножить на 10, сложить с числом 11100, разделить на 5. Вывести полученный результат.( среда, ассемблер 16 битный под DOS , tasm и tlink , использо... Вопрос № 181589: Здравствуйте, уважаемые эксперты! Прошу решить задачу:Ввести число 95347. Вычесть из него число 27358, умножить на 10, сложить с числом 11100, разделить на 5. Вывести полученный результат.( среда, ассемблер 16 битный под DOS , tasm и tlink , использовать модель памяти small). Большая просьба написать комнтарий к каждой строчке, а то я ничего не понимаю в асемблере. Отправлен: 24.12.2010, 16:29 Вопрос задал: Артем Воробьев (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, Артем Воробьев! А вот и программа, "с пылу, с жару" Задание предусматривает умножение/деление, когда результат не помещается в слово Надо использовать двойные слова. Это раз. Второе: задание так построено, что обычные 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 add ax, 11100 adc dx, 0 ;dx:ax = dx:ax + 11100
push 5 push ax push dx call Div_DW_W ;разделим dx:ax на 5
push ax push dx call PrintNum ;выведем dx:ax
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 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий