Ввод с клавиатуры и вывод на экран - Assembler
Формулировка задачи:
Изучаю совсем недавно ASM, изучение идёт ну очееень тяжело.
Помогите пожалуйста всё "по полочкам" разложить. Перечитала многое, всё равно не могу понять что да как.
Программу помогли исправить ( за что огромное спасибо), но как её же переписать под ввод-вывод не понимаю.
Уравнение, которые описано в программе: F= (12563 / 78)+ X -(Y *2852)
masm Model small .386 .stack 400h .data x dd 3h y dd 4h f dd ? .code start: mov ax,@data mov ds,ax mov eax,Y mov ebx,2852 imul ebx;edx:eax=Y *2852 mov esi,eax mov edi,edx mov eax,12563 cdq; edx=0 or edx=-1 mov ebx,78 idiv ebx; eax=12563/78 cdq add eax,X adc edx,0;edx:eax= (12563 / 78)+ X sub eax,esi sbb edx,edi;edx:eax= (12563 / 78)+ X -(Y *2852) mov f, eax mov ax,4c00h int 21h end start
Решение задачи: «Ввод с клавиатуры и вывод на экран»
textual
Листинг программы
;F= (12563 / 78)+ X -(Y *2852) LOCALS .model small .stack 100h .data CrLf db 0Dh, 0Ah, '$' PromptGetX db 'Input X (-32768..+32767): ', '$' PromptGetY db 'Input Y (-32768..+32767): ', '$' KeyBuf db 7, 0, 8 dup(0) ;max,len,string,CR(0dh) msgError db 'Ошибка ввода числа', 0Dh, 0Ah, '$' X dw ? Y dw ? F dw ? .code main proc mov ax, @data mov ds, ax @@GetX: ; ввод числа с клавиатуры (строки) lea dx, PromptGetX mov ah,09h int 21h mov ah, 0Ah mov dx, offset KeyBuf int 21h ; перевод строки (на новую строку) lea dx, CrLf mov ah,09h int 21h ; преобразование строки в число lea si, KeyBuf+1 lea di, X call Str2Num ; проверка на ошибку jnc @@GetY ; если есть ошибка ввода - напечатать сообщение об ошибке lea dx, msgError mov ah,09h int 21h jmp @@GetX @@GetY: ; ввод числа с клавиатуры (строки) lea dx, PromptGetY mov ah,09h int 21h mov ah, 0Ah mov dx, offset KeyBuf int 21h ; перевод строки (на новую строку) lea dx, CrLf mov ah,09h int 21h ; преобразование строки в число lea si, KeyBuf+1 lea di, Y call Str2Num ; проверка на ошибку jnc @@Calc ; если есть ошибка ввода - напечатать сообщение об ошибке lea dx, msgError mov ah,09h int 21h jmp @@GetY @@Calc: ;F= (12563 / 78)+ X -(Y *2852) mov ax, 12563 cwd mov bx, 78 idiv bx ;ax:= (12563 / 78) add ax, X ;ax:= (12563 / 78) + X mov bx, ax ;bx:= (12563 / 78) + X mov ax, 2852 imul Y ;ax:= Y*2852 sub bx, ax ;bx:=(12563 / 78)+ X -(Y *2852) mov F, bx mov ax, F call Show_AX mov ax, 4C00h int 21h main endp ; выводит число из регистра AX на экран ; входные данные: ; ax - число для отображения Show_AX proc push ax push bx push cx push dx push di mov cx, 10 xor di, di ; di - кол. цифр в числе ; если число в ax отрицательное, то ;1) напечатать '-' ;2) сделать ax положительным or ax, ax jns @@Conv push ax mov dx, '-' mov ah, 2 ; ah - функция вывода символа на экран int 21h pop ax neg ax @@Conv: xor dx, dx div cx ; dl = num mod 10 add dl, '0' ; перевод в символьный формат inc di push dx ; складываем в стэк or ax, ax jnz @@Conv ; выводим из стэка на экран @@Show: pop dx ; dl = очередной символ mov ah, 2 ; ah - функция вывода символа на экран int 21h dec di ; повторяем пока di<>0 jnz @@Show pop di pop dx pop cx pop bx pop ax ret Show_AX endp ; преобразования строки в число ; на входе: ; ds:[si] - строка с числом ; ds:[di] - адрес числа ; на выходе ; ds:[di] - число ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен) Str2Num proc push ax push bx push cx push dx push ds push es push si push ds pop es mov cl, ds:[si] xor ch, ch inc si mov bx, 10 xor ax, ax ;если в строке первый символ '-' ; - перейти к следующему ; - уменьшить количество рассматриваемых символов cmp byte ptr [si], '-' jne @@Loop inc si dec cx @@Loop: mul bx ; умножаем ax на 10 ( dx:ax=ax*bx ) mov [di], ax ; игнорируем старшее слово cmp dx, 0 ; проверяем, результат на переполнение jnz @@Error mov al, [si] ; Преобразуем следующий символ в число cmp al, '0' jb @@Error cmp al, '9' ja @@Error sub al, '0' xor ah, ah add ax, [di] jc @@Error ; Если сумма больше 65535 cmp ax, 8000h ja @@Error inc si loop @@Loop pop si ;проверка на знак push si inc si cmp byte ptr [si], '-' jne @@Check ;если должно быть положительным neg ax ;если должно быть отрицательным jmp @@StoreRes @@Check: ;дополнительная проверка, когда при вводе положительного числа получили отрицательное or ax, ax ; js @@Error @@StoreRes: ;сохранить результат mov [di], ax clc pop si pop es pop ds pop dx pop cx pop bx pop ax ret @@Error: xor ax, ax mov [di], ax stc pop si pop es pop ds pop dx pop cx pop bx pop ax ret Str2Num endp end main
Объяснение кода листинга программы
- Создаются переменные с помощью директивы
.data
:CrLf
- символ новой строкиPromptGetX
- строка с текстомInput X (-32768..+32767):
PromptGetY
- строка с текстомInput Y (-32768..+32767):
KeyBuf
- массив для ввода текста с клавиатурыmsgError
- строка с сообщением об ошибкеX
- переменная для хранения значения XY
- переменная для хранения значения YF
- переменная для результата расчета
- В процедуре
main
выполняется обработка ввода пользователя:- Вводится значение X
- Преобразуется значение X в число
- Проверяется наличие ошибок ввода
- Вводится значение Y
- Преобразуется значение Y в число
- Проверяется наличие ошибок ввода
- Рассчитывается значение
F
:- Выполняются математические операции с числами (12563, 78, X, Y, 2852)
- Результат сохраняется в переменной
F
.
- Вызывается процедура
Show_AX
для вывода значения переменнойF
на экран. - Программа завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д