 |
Ассемблер в примерах - Простейший калькулятор
- Вопрос:
- Помогите пожалуйста разработать простейший калькулятор, выполняющий сложение, умножение и вычитание целых чисел в диапазоне от 0 до 9.
- Ответ:
-
.model tiny
.code
JUMPS ; эта директива заставляет генерировать код, при котором можно писать условные
; переходы на расстояние больше 128 байт (а тут такие есть)
org 100h
start:
mov ax, 3
int 10h
@@00:
lea dx, msg_first
CALL inputDEC
mov a, al
lea dx, msg_second
CALL inputDEC
mov b, al
lea dx, msg_op
mov ah, 9
int 21h
op01:
mov ah, 8
int 21h
cmp al, '*'
je op_mul
cmp al, '+'
je op_add
cmp al, '-'
je op_sub
cmp al, '/'
je op_div
jmp op01 ; все остальные игнорируем
op_mul:
mov op, al
mov al, a
mov ah, b
imul ah
mov c, al
jmp show_result
op_add:
mov op, al
mov al, a
add al, b
mov c, al
jmp show_result
op_sub:
mov op, al
mov al, a
sub al, b
mov c, al
jmp show_result
op_div:
mov op, al
mov bl, b
or bl, bl
jz op_no_div
mov al, a
cbw ; конвертировать байт в слово с сохранением знака
idiv bl ; знаковое деление
mov c, al
jmp show_result
op_no_div:
lea dx, msg_no_div
mov ah, 9
int 21h
jmp op_repeat
show_result:
lea dx, msg_res
mov ah,9
int 21h
mov al, a
CALL writeDEC
mov al, op
int 29h
mov al, b
CALL writeDEC
mov al, '='
int 29h
mov al, c
CALL writeDEC
op_repeat:
lea dx, msg_repeat
mov ah, 9
int 21h
mov ah, 8
int 21h
cmp al, 'y'
je @@00
cmp al, 'Y'
je @@00
jmp @@_exit
lea dx, PressKey
mov ah,9
int 21h
xor ax, ax
int 16h
@@_exit:
int 20h
inputDEC proc
; возвратит число со знаком в AL
; при вводе в DX - адрес сообщения
push bx
mov ah, 9
int 21h
xor bl, bl ; число
xor bh, bh ; флаг отрицательного будет
@@1_01:
mov ah, 8
int 21h
cmp al, '-'
jne @@1_digit
inc bh
int 29h ; покажем
jmp @@1_01
@@1_digit:
cmp al, '0'
jb @@1_01 ; меньше нуля - игнорируем
cmp al, '9'
ja @@1_01
; значит цифра
int 29h
sub al, '0' ; число и символ числа отличаются на код '0'
or bh, bh ; проверим, установлен ли
jz @@1_positive
neg al
@@1_positive:
pop bx
ret
inputDEC endp
writeDEC proc
; вывод числа в AL как десятичного со знаком
; -128 .. + 127
push ax
push bx
push cx
push dx
or al, al
jns @@positive ; если не установлен флаг знака
push ax
mov ah, 2
mov dl, '-'
int 21h
pop ax
neg al
@@positive:
xor cx, cx
mov bl, 10
@@next_digit:
xor ah, ah
div bl
push ax
inc cx
or al, al
jnz @@next_digit
@@out_next_digit:
pop ax
xchg ah, al
add al, '0'
int 29h
LOOP @@out_next_digit
pop dx
pop cx
pop bx
pop ax
ret
writeDEC endp
a db ? ; первое число
b db ? ; второе число
c db ? ; результат
op db ?
msg_first db 13,10,'Введите первое число: $'
msg_second db 13,10,'Введите второе число: $'
msg_op db 13,10,'Введите знак операции (+,-,*,/): $'
msg_res db 13,10,'Результат: $'
msg_repeat db 13,10,'Повторить (Y/N)$'
msg_no_div db 13,10,'Деление невозможно$'
PressKey db 13,10,'Press any key ...$'
end start
|  |