Примитивный калькулятор (два операнда и операции сложения, вычитания, умножения и деления) - Assembler/MASM

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Вот пытался написать примитивный калькулятор, которые будет +, -, * и / два значения, введенные пользователём, только есть одно условие, пользователь должен одним вводом ввести уравнение, например, 3 + 5 6 – 3 2 * 2 или 6 / 2 Мне нужно чтобы программа считывала какой знак был введен между цыфрами и на его основе производить вычесления. Была идея, чтобы сохранять введенную пользователем строку в одной переменной, например, userInput DW '3 + 5', а затем разбить данную строку на три значения, firstNumber DW '3', operator DW '+' и secondNumber DW '5'. При создании я не должен использовать библиотечные функции и код должен быть написан на Masm32. К сожалению, моих знаний и практики не достаточно чтобы выполнить подобную задачу. Буду благодарен за любой пример.

Решение задачи: «Примитивный калькулятор (два операнда и операции сложения, вычитания, умножения и деления)»

textual
Листинг программы
.686
.model flat, stdcall
option casemap :none
 
        include \masm32\include\windows.inc
 
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\masm32.inc
 
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
.data
        aszPrompt       db      'Expression: ', 0Dh, 0Ah, 0
        aszPressEnter   db      0Dh, 0Ah, 0Dh, 0Ah, "Press ENTER to exit", 0
        aszResult       db      10, 13, "Result of your equation is %d", 0
 
        OpAdd           equ     '+'
        OpSub           equ     '-'
        OpMul           equ     '*'
        OpDiv           equ     '/'
 
        AllowedChars    db      '=+-*/0123456789'
        LenAllowedChars equ     $-AllowedChars
        OpChars         db      '=+-*/'
        LenOpChars      equ     $-OpChars
.data?
        hConsoleOutput  HANDLE  ?
        hConsoleInput   HANDLE  ?
        Buffer          db      1024 dup(?)
        BufLen          dd      ?
        Result          dd      ?
        Op1             dd      ?
        Op2             dd      ?
        Operation       db      ?
.code
 
PrevOperation   proc
                mov     eax,    [Op1]
                cdq
                mov     ebx,    [Op2]
                cmp     [Operation],    OpAdd
                jne     @@Sub
                add     eax,    ebx
                jmp     @@Calc
        @@Sub:
                cmp     [Operation],    OpSub
                jne     @@Mul
                sub     eax,    ebx
                jmp     @@Calc
        @@Mul:
                cmp     [Operation],    OpMul
                jne     @@Div
                mul     ebx
        @@Div:
                cmp     [Operation],    OpDiv
                jne     @@Calc
                idiv    ebx
        @@Calc:
                mov     [Op1],  eax
                mov     [Op2],  0
                mov     al,     [esi-1]
                mov     [Operation],    al
        ret
PrevOperation   endp
 
main    proc
 
        ; получение описателей ввода и вывода консоли
        invoke  GetStdHandle,   STD_INPUT_HANDLE
        mov     hConsoleInput,  eax
 
        invoke  GetStdHandle,   STD_OUTPUT_HANDLE
        mov     hConsoleOutput, eax
 
        invoke  ClearScreen
 
        ;ввод выражения
        invoke  WriteConsole, hConsoleOutput, ADDR aszPrompt,\
                LENGTHOF aszPrompt-1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR Buffer,\
                LENGTHOF Buffer, ADDR BufLen, NULL
        lea     esi,    [Buffer]        ;удаление из буфера
        add     esi,    [BufLen]        ;символов перевода строки
        mov     [esi-2],word ptr 0
        sub     [BufLen],       2
 
        ;обработка выражения во введённой строке
        mov     eax,    0
        mov     [Op1],  0
        mov     [Op2],  0
        mov     [Operation],    OpAdd
 
        lea     esi,    [Buffer]
        mov     ecx,    [BufLen]
        @@GetCmd:
                push    ecx
                lodsb
                ;проверка корректности введённых символов
                lea     edi,    [AllowedChars]
                mov     ecx,    [LenAllowedChars]
                repne   scasb
                jnz     @@Next
        @@ProcessChar:
                lea     edi,    [OpChars]
                mov     ecx,    [LenOpChars]
                repne   scasb
                jz      @@DoOperation
        @@TestDigits:
                ;введена цифра
                and     eax,    0FFh
                sub     al,     '0'
                mov     ebx,    [Op2]
                lea     eax,    [eax+8*ebx]
                lea     eax,    [eax+2*ebx]
                mov     [Op2],  eax
 
                pop     ecx
                push    ecx
                cmp     ecx,    1
                jne     @@Next
 
        @@DoOperation:
                ;сначала завершается предыдущая операция
                call    PrevOperation
                cmp     al,     '='
                jne     @@Next
                pop     ecx
                jmp     @@Break
        @@Next:
                pop     ecx
        loop    @@GetCmd
@@Break:
ResultShow:
        ;вывод результата
        mov     eax,    [Op1]
        invoke  wsprintf, ADDR Buffer, ADDR aszResult, eax
        mov     [BufLen],       eax
        invoke  WriteConsole, hConsoleOutput, ADDR Buffer,\
                BufLen, ADDR BufLen, NULL
 
        ;ожидание нажатия ENTER
        invoke  WriteConsole, hConsoleOutput, ADDR aszPressEnter,\
                LENGTHOF aszPressEnter - 1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR Buffer,\
                LENGTHOF Buffer, ADDR BufLen, NULL
 
        invoke  ExitProcess, 0
main    endp
 
end     main

Объяснение кода листинга программы

В данном коде представлена простая реализация примитивного калькулятора на языке ассемблера. Список переменных и их значений:

  1. [Op1], [Op2] - переменные, используемые для хранения операндов и результата операций.
  2. [Operation] - переменная, используемая для хранения текущей операции.
  3. [BufLen] - переменная, используемая для хранения количества символов в буфере ввода.
  4. [AllowedChars] - строка, содержащая набор допустимых символов для ввода.
  5. [OpChars] - строка, содержащая набор символов операций.
  6. [aszPrompt], [aszPressEnter], [aszResult] - строки, содержащие текстовые сообщения для пользователя. Список действий:
  7. Получение дескрипторов стандартного ввода и вывода консоли.
  8. Очистка экрана.
  9. Ввод выражения с помощью функции ReadConsole.
  10. Обработка введенного выражения: проверка корректности введенных символов и выполнение операций.
  11. Вывод результата с помощью функции WriteConsole.
  12. Ожидание нажатия ENTER с помощью функции ReadConsole.
  13. Завершение работы программы с помощью функции ExitProcess.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

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