Написать программу, позволяющую выполнять арифметические действия над двоичными или шестнадцатеричными числами - 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

Оцени полезность:

7   голосов , оценка 4.143 из 5
Похожие ответы