Написать программу, позволяющую выполнять арифметические действия над двоичными или шестнадцатеричными числами - Assembler
Формулировка задачи:
Доброго времени суток! Подскажите пожалуйста как реализовать данную задачу, заранее большое спасибо!
Написать программу, позволяющую выполнять арифметические действия над двоичными или шестнадцатеричными числами.
Систему счисления выбирает пользователь. Предусмотреть возможность сохранения результатов всех выполненных действий в файл.
Решение задачи: «Написать программу, позволяющую выполнять арифметические действия над двоичными или шестнадцатеричными числами»
textual
Листинг программы
.model tiny .code org 100h main proc jmp start OpMul equ '*' OpDiv equ '/' OpAdd equ '+' OpSub equ '-' ;Данные BinChars db '01' LenBinChars dw $-BinChars HexChars db '0123456789ABCDEFabcdef' LenHexChars dw $-HexChars OpChars db '=+-*/' LenOpChars dw $-OpChars CrLf db 0Dh, 0Ah, '$' msgPromptBase db 'Select the base (bin/hex)? (b/h) ', '$' msgPromptExpr db 0Dh, 0Ah, 'Expression: ', '$' msgResult db 'Result: ', '$' msgPressAnyKey db 0Dh, 0Ah, 'Press any key to exit...', '$' BaseChars dw ? BaseCharsLen dw ? Base dw ? FirstNumb dw ? SecondNumb dw ? Operation db ? CurrChar db ? kbdBuf db 80, 81 dup(?) start: ;программа ;ввод основания счисления mov ah, 09h lea dx, [msgPromptBase] int 21h @@GetBase: mov ah, 00h int 16h cmp al, 'b' je @@StoreBase cmp al, 'h' je @@StoreBase jmp @@GetBase @@StoreBase: int 29h lea bx, [BinChars] mov [BaseChars], bx mov bx, [LenBinChars] mov [BaseCharsLen], bx mov [Base], 2 cmp al, 'b' je @@Base lea bx, [HexChars] mov [BaseChars], bx mov bx, [LenHexChars] mov [BaseCharsLen], bx mov [Base], 16 @@Base: ;ввод чисел и операций mov ah, 09h lea dx, [msgPromptExpr] int 21h mov [FirstNumb], 0 mov [SecondNumb], 0 mov [Operation], OpAdd @@GetCmd: mov ah, 00h int 16h mov [CurrChar], al ;проверка корректности введённых символов lea di, [OpChars] mov cx, [LenOpChars] repne scasb jnz @@TestDigits int 29h jmp @@DoOperation @@TestDigits: mov di, [BaseChars] mov cx, [BaseCharsLen] repne scasb jnz @@GetCmd int 29h ;введена цифра sub al, '0' cmp al, 9 jbe @@DoDigit sub al, 'A'-'0'+10 cmp al, 15 jbe @@DoDigit sub al, 'a'-'A' @@DoDigit: mov bx, 0 mov bl, al mov ax, [SecondNumb] mul [Base] add ax, bx mov [SecondNumb], ax jmp @@GetCmd @@DoOperation: ;сначала завершается предыдущая операция mov ax, [FirstNumb] mov dx, 0 mov bx, [SecondNumb] cmp [Operation], '+' jne @@Sub add ax, bx jmp @@Calc @@Sub: cmp [Operation], '-' jne @@Mul sub ax, bx jmp @@Calc @@Mul: cmp [Operation], '*' jne @@Div mul bx @@Div: cmp [Operation], '/' jne @@Calc div bx @@Calc: mov [FirstNumb], ax mov [SecondNumb], 0 mov al, [CurrChar] mov [Operation], al cmp al, '=' je @@Break jmp @@GetCmd @@Break: mov ax, [FirstNumb] cmp [Base], 2 jne @@ShowResHex call ShowBin jmp @@NewLine @@ShowResHex: call ShowHex @@NewLine: mov ah, 09h lea dx, [msgPressAnyKey] int 21h mov ah, 00h int 16h int 20h main endp ;выводит на экран в 16 системе счисления содержимое регистра AX ; входные данные: ; ax - число для отображения ShowHex proc push ax push cx push dx ; Начинаем перевод числа AX в строку mov cl, ((16-1)/4)*4 ; 16-битный регистр, будем выводить по 4 бита (0..F) xchg dx, ax ; Сохраняем число в DX @@Repeat: mov ax, dx ; Восстанавливаем число в AX shr ax, cl ; Сдвигаем на CL бит вправо and al, 0Fh ; Получаем в AL цифру 0..15 add al, '0' ; Получаем в AL символ цифры cmp al, '9' ; Проверяем цифру jbe @@Digit09 ; Прыгаем, если это цифра 0..9 add al, 'A'-('9'+1) ; Иначе (для A..F) корректируем ее @@Digit09: int 29h ; Выводим символ в AL на экран sub cl, 4 ; Уменьшаем CL на 4 для следующей цифры jnc @@Repeat ; Если знаковый CL >= 0, то повторяем pop dx pop cx pop ax ret ShowHex endp ;выводит на экран в двоичной системе счисления содержимое регистра AX ; входные данные: ; ax - число для отображения ShowBin proc push ax push bx push cx mov bx, ax ; из-за распределения регистров ; при выводе на экран с помощью int 29h, ; выводимое число будет находится в bx mov cx, 16 ; переменная цикла равна количеству бит в слове @@For: mov ax, '0' ; в регистрах al=код символа '0', ah=00h shl bx, 1 ; выделение бита adc al, ah ; сложение кода символа '0' со значением выделенного бита int 29h loop @@For pop cx pop bx pop ax ret ShowBin endp end main