Skip to content

Wynneve/assembly-calculator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Калькулятор на ассемблере

Это калькулятор арифметических выражений, написанный на языке 64-битного варианта Microsoft Assembler (MASM64) под ОС Windows.

Этот проект был написан мной из чистого интереса в качестве первой хоть сколько-то масштабной программы на ассемблере, в основном в целях практики. Интересно, что калькулятор такого рода на языках высокого уровня я до этого никогда не писал.

Возможности

Этот калькулятор умеет вычислять арифметические выражения, записанные в традиционной инфиксной нотации.

Поддерживаются:

  • числа, целые или дробные; десятичный разделитель — точка
  • четыре арифметических действия (+, -, *, /), в том числе унарный минус
  • вложенные выражения в скобках (), произвольной глубины

Ограничения

Во-первых, очевидно, что код не кроссплатформенный. Программа динамически линкуется с kernel32.dll и задействует функции API ядра Windows, в числе которых: GetStdHandle, WriteConsole, ReadConsole, HeapAlloc, ExitProcess.

Во-вторых, как следствие упрощения кода, калькулятор не валидирует синтаксис выражений, за исключением обработки неизвестных токенов, поэтому некорректные выражения, например, с несбалансированными скобками или нарушенной нотацией операций, могут как частично вычислиться, так и привести к краху программы.

Устройство

Программа работает в цикле. Каждое введённое выражение проходит через три стадии:

  1. Лексинг. Символы и числа превращаются в отдельные токены. Это нужно как для удобства обработки в дальнейшем, так и для распознавания записанных чисел сразу. Отдельно для этого пришлось написать процедуру для перевода числа из его строкового представления. Программа работает с числами в формате с плавающей запятой двойной точности, однако моя упрощённая реализация ограничивает точность 9 знаками до и после запятой.

  2. Парсинг. Цепочка токенов переводится в формат, пригодный для вычисления в дальнейшем. В результате получается прямая (префиксная) запись — это оказалось удобнее, хотя обычно и применяется обратная (постфиксная) запись.
    Алгоритм я придумал сам, не изучив предварительно имеющиеся подходы. Потом оказалось, что получилось что-то вроде алгоритма Дейкстры, но с рекурсией. Мой алгоритм наверняка не оптимален, но показался мне самым простым и очевидным.

  3. Вычисление. Поскольку легче оказалось создать прямую запись, а для вычислений пригодней обратная, приходится обходить результат парсинга с конца до начала, в обратном порядке. Числа помещаются на стек, а операции производятся над числами на верхушке стека: бинарные над парами, унарные над одиночными. Результат помещается обратно на стек. В конце должно остаться одно число, которое и будет значением выражения.

После этого результат выводится на экран, для чего пришлось также написать процедуру перевода числа в его строковое представление, работающую с той же точностью, что и её распознающая пара.

Планы

Разработка

  • Покрытие тестами для упрощения разработки в будущем

Код

  • Написание эквивалентного псевдокода для облегчения восприятия
  • Рефакторинг кода, в частности — токенизации
  • Более полезное и точное покрытие комментариями
  • Написание версии под Linux, из чистого интереса

Арифметика

  • Валидация синтаксиса выражений
  • Добавление математических функций (идентификаторы со скобками)
  • Добавление возведения в степень (+ 1 уровень приоритета!)

Память

  • Освобождение выделенной памяти после каждой итерации цикла
  • Более аккуратное, то есть точное, выделение памяти

Поведение

  • Возвращение в цикл после ошибки вместо завершения программы
  • Вывод более информативных сообщений об ошибках

Сборка

Требуется наличие Microsoft Visual Studio Build Tools, поэтому процесс сборки тоже ограничен ОС Windows. После установки компонента для нативной разработки нужно запустить x64 Native Tools Command Prompt и перейти в корень репозитория, после чего надо исполнить скрипт build.cmd. В результате появится исполняемый файл app.exe.

Пример работы в терминале

Expression calculator.

> 2+2
= 4.0

> 1 - 2 - 3
= -4.0

> 2 + 2*2
= 6.0

> 1 + 23.8 * (-31 + 445 * 53) - 67
= 560519.2

> 1 + 2 * 3 / 4 + 5 - 6 - (-7)*8 + 9
= 66.5

> 1 + 23 * (2 * 31 + 2 * 45/53) - 67 / 2
= 1432.556603774

> 43252 * 0.011 + 0.1 / 2 - (2 + 2 * 1.2) + 2 * (1 + (-1))
= 471.422

> 5/8*3
= 1.875

> 1/2/3/4
= 0.041666667

> 1/2-3/4
= -0.25

> 1 - (1 - (1 - (1 - (1 - 1))))
= 0.0

>

About

Калькулятор на ассемблере

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors