Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2674
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2279
∙ повысить рейтинг »
vladisslav
Статус: 8-й класс
Рейтинг: 1318
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска: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 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.25 от 13.12.2010

    В избранное