Программа-калькулятор, позволяющая пользователю выполнять четыре основных арифметических действия над числами, укладывающимися в 8-байтовый диапазон
ПРОЕКТИРОВАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА Входными данными являются 2а числа (обязательно со знаком), участвующие в вычислении, символ операции (+, -, *, /). При вводе некорректных численных знаков и символов операции действий не выполняется, так как программа находится в ожидании одного из необходимых символов и не продолжит работу до его ввода. При вводе некорректных числовых значений… Читать ещё >
Программа-калькулятор, позволяющая пользователю выполнять четыре основных арифметических действия над числами, укладывающимися в 8-байтовый диапазон (реферат, курсовая, диплом, контрольная)
Московский Энергетический Институт Институт автоматики и вычислительной техники Кафедра ВМСС Курсовая работа по дисциплине
«Системное программное обеспечение»
Тема: Программа-калькулятор, позволяющая пользователю выполнять четыре основных арифметических действия над числами, укладывающимися в 8-байтовый диапазон Студент: Резвая Г. В.
Принял: Чернов С.А.
Москва 2011
1. Анализ задания
2. Проектирование пользовательского интерфейса
3. Выбор формата представления данных
4. Макросы, процедуры, их назначение
5. Используемые функции, их назначение
6. Тестирование и отладка Заключение Список литературы Приложение А. Листинг программы ВВЕДЕНИЕ Проведение четырех основных арифметических операций над целыми числами — подзадача, реализованная в большинстве пользовательских программ (как явно, так и неявно). Решение данной задачи требует не столько обширных знаний языка Ассемблер, сколько практических навыков работы. Реализация многоэтапных алгоритмов вычисления требует использования многочисленных операторов и функций языка.
1. АНАЛИЗ ЗАДАНИЯ Техническое задание: Разработать программу-калькулятор, позволяющую пользователю выполнять четыре основных арифметических действия над числами, укладывающимися в 8-байтовый диапазон.
Разобьем задачу на подзадачи:
— считывание чисел из командной строки;
— считывание символа операции;
— исходя из значения символа операции, выполнение необходимых вычислений;
— вывод результата;
— обработка исключений (например: проверка на корректность введенных символов; проверка на нулевой делитель, при выполнении операции деления и т. п.).
По заданию числа должны укладываться в 8-байтовый диапазон. Было принято решение производить вычисления в 10-ричном формате (так как алгоритмы вычисления нетривиальны, в отличие от вычислений в 2-ном формате), отсюда следует, что одному разряду числа будет соответствовать один байт памяти, также один байт памяти должен быть выделен, на хранение знака (1 байт — знак + 7 байт — число = 8 байт).
2. ПРОЕКТИРОВАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА Входными данными являются 2а числа (обязательно со знаком), участвующие в вычислении, символ операции (+, -, *, /). При вводе некорректных численных знаков и символов операции действий не выполняется, так как программа находится в ожидании одного из необходимых символов и не продолжит работу до его ввода. При вводе некорректных числовых значений выводится сообщение об ошибке и приглашение повторить попытку ввода данных.
Если происходит то или иное исключение (например: пользователь ввел нулевой делитель при выполни операции деления), выводится сообщение об ошибки с понятным комментарием и приглашение повторить попытку ввода данных.
Выходными данными является результат выбранной операции со знаком (если не произошло исключений).
После выполнения операции можно выполнить следующую. Чтобы выйти из программы нужно записать символ q или Q при приглашении ввести символ операции.
3. ВЫБОР ФОРМАТА ПРЕДСТАВЛЕНИЯ ДАННЫХ Для определения данных в программе используются следующие директивы: db (байт), dq (учетверенное слово). В таблице 1 перечислены переменные, которые фигурируют в программе. Переменные, которые используются для удобства (при просмотре состояния памяти через отладчик) в таблице не приведены.
Таблица 1
Имя | Директива | Назначение | |
string1 | db | «Введите число» | |
string2 | db | «Выберите операцию» | |
string3 | db | «Введено некорректное число. Попробуйте снова» | |
string4 | db | «Некорректная операция. a | |
string5 | db | Перевод каретки | |
string6 | db | «Результат операции» | |
string7 | db | «Некорректная операция. b=0. Попробуйте снова» | |
chastnoe | dq | Результат операции деления. (Частное) | |
bufer01 | dq | Считанное с клавиатуры 1е число | |
numbe01 | dq | Переписанное 1 число. Запись справа налево, начиная с младших разрядов | |
bufer02 | dq | Считанное с клавиатуры 2е число | |
numbe02 | dq | Переписанное 2 число. Запись справа налево, начиная с младших разрядов | |
bufer03 | dq | Результат операций (сложение, вычитание) | |
bufer04 | dq | Промежуточный результат деления, умножения | |
flag | db | Результат сравнения 2х чисел (00 — a > b, 01 — a < b) | |
flag2 | db | Вспомогательный флаг при выполнении деления | |
flag01 | db | Хранит знак 1 числа | |
flag02 | db | Хранит знак 2 числа | |
flag03 | db | Хранит знак результата | |
4. МАКРОСЫ, ПРОЦЕДУРЫ, ИХ НАЗНАЧЕНИЕ программа макрос алгоритм Список макросов, процедур и описание их функциональной нагрузки приведено в таблице 2.
Таблица 2
Макросы | ||
Вывод строки | ||
znak | Считывание знака числа (+, -) | |
read_b | Считывание строки в буфер из консоли | |
perep | Перенос числа из буфера в память, начиная с правого края | |
perem | Меняем местами 2а числа в памяти | |
set_flag | Установка знака результата операции | |
nuli | Обрезаем лидирующие нули. Проверяем нулевое ли число | |
smesh | Передвигаем разряд на одну ячейку влево. В указанном отрезке памяти | |
read_kl | Считывание символа операции | |
Процедуры | ||
clear | Очистка экрана | |
srav | Сравниваем 2а числа | |
zp_znak | Считываем знак числа из консоли | |
och_bufer | Очищаем выбранный отрезок памяти | |
p_sloj | Сложение | |
p_vich | Вычитание | |
p_umno | Умножение | |
p_dele | Деление | |
vivod | Вывод результата операции | |
vivod2 | Вывод большого результата операции (для умножения) | |
5. ИСПОЛЬЗУЕМЫЕ ФУНКЦИИ, ИХ НАЗНАЧЕНИЕ В программе используется следующие функции:
1. Очистка экрана Функция 03h прерывания 10h
ah = [00 — необходимый видеорежим]
2. Ввод с клавиатуры с буферизацией Функция 0Ah прерывания 21h
dx = [адрес буфера]
3. Вывод строки символов на экран Функция 09h прерывания 21h
dx = [адрес строки]
4. Ввод символа с клавиатуры с эхом на экран Функция 01h прерывания 21h
Считывает ASCII-код символа в al
5. Завершение программы Функция 00h прерывания 21h
6. Вывод символа на экран Функция 02h прерывания 21h
dl = [выводимый символ]
6. ТЕСТИРОВАНИЕ И ОТЛАДКА При тестировании программы были выявлены исключение, для которых необходима обработка:
1. В качестве знака числа пользователь может ввести исключительно «+» или «-».
2. В качестве разряда числа пользователь может ввести цифры. В противном случае выводим сообщение об ошибке.
3. В качестве символа операции пользователь может ввести исключительно символы «+», «-», «*», «/» и символы, обеспечивающие выход из программы «q», «Q».
4. При попытке выполнить деление на делитель больше делимого выводим ошибку. (можно было выводить 0, но ошибка нагляднее).
5. При попытке выполнить деление на 0 выводим сообщение об ошибке.
6. При вводевыводе нулей в старших разрядах лидирующие нули игнорируются. Происходит вводвывод, начиная с первой значащей цифры.
7. Предусмотрена работа как с положительными числами, так и с отрицательными.
ЗАКЛЮЧЕНИЕ
В курсовом проекте была разработана программа-калькулятор, реализующая выполнение четырех основных арифметических операций. Программа работоспособна и соответствует заявленным требованиям.
Программа может быть улучшена за счет расширения диапазонов входных данных. Также можно дополнить функционально: работа с числами в двоичном и шестнадцатеричном форматах. Доработкой может являться: увеличение числа операций над входными данными, например вычисление модуля числа, вычисление квадратного корня; работа с дробными значениями.
1. Абель П., Язык ассемблера для IBM PC и программирования — М.: Высшая школа, 1992. — 447 с.
2. Юров В. И., Assembler. Учебник для вузов. 2-е издание — СПБ.: Питер, 2003. 638 с.
ПРИЛОЖЕНИЕ А. ЛИСТИНГ ПРОГРАММЫ
;17. Программа-калькулятор, позволяющая пользователю выполнять четыре основных
;арифметических действия над целыми числами, укладывающимися в 8-байтовый диапазон.
;———————макросы——————————-;
;——вывод строки—————————————;
print macro str;в str заносим адрес строки для вывода
mov ah, 09h;функция вывода 21го прерывания
lea dx, str;адрес строки в dx
int 21h;вызов прерывания 21h
endm
;——считывание знака операции——————-;
znakmacro flag1, b08, b09
print string1;макрос вывода строки «Введите число: «
xor ax, ax;обнуляем регистры
xor dx, dx
mov ah, 01h;функция считывания символа с клавиатуры (с эхо)
int 21h;вызов прерывания 21h
cmp al, '+';сравнение с '+'
je b09
cmp al, '-';сравнение с '-'
je b09
jmp b08;пока знак операции не будет введен игнорируем
b09:
lea di, flag1;запись знака в соотв место памяти знака
mov [di], al
endm
;——считывание строки в буфер——————-;
;первый байт буфера должен содержать мах длину
;второй байт содержит факт длину по возвращению
read_bmacro str;в str заносим адрес буфера для ввода
mov ah, 0Ah;функция считывание строки в буфер
lea dx, str;адрес буфера в dx
int 21h;вызов прерывания 21h
print string5;макрос вывода строки (переноса каретки)
endm
;——перенос в правую часть буфера————-;
perepmacro buf, numb, a28, b23,b24
lea di, buf+1;перенос числа из буферной памяти
mov cx, [di]; в память, начиная с правого края
xor ch, ch;необходимого отрезка памяти
add di, cx
lea si, numb+8
a28:
mov ax, [di]
cmp al, byte ptr 29h;проверка на корректность вводимых данных
jbe b23;переход, если ниже или равно
cmp al, byte ptr 40h
jae b23;переход, если выше или равно
mov [si], ax
dec si
dec di
loop a28
jmp b24
b23:
print string3;вывод строки «введен некорректный символ операции»
print string5
jmp b111;начнем сначала
b24:
endm
;——перемещение местами—————————-;
peremmacro a00;меняем местами два числа
lea di, numbe01+1;чтобы упростить алгоритм работы со знаками
lea si, numbe02+1;чтобы первое всегда было больше
mov cx, 8
a00:
mov al, [di]
mov bl, [si]
mov [si], al
mov [di], bl
inc di
inc si
loop a00
endm
;——установка знака ответа————————;
set_flag macro f00, b07;запись в флаг того, что насчитали
lea di, flag03
mov [di], byte ptr f00
jmp b07
endm
;——работа с нулями (обрезка/проверка)——;
nuli macro a78, a69,a70
a69:;обрезаем лидирующие нули
mov al,[si]
cmp al, 00h;вдруг уже не ноль
jne a78
inc si
loop a69
a78:;вдруг прописаны только нули
mov al,[si]
cmp al, 30h
jne a70
mov al, 00h;заменям нули на нули (30h на 00h)
mov [si], al
inc si
loop a78
endm
;——смещение разрядов внутри буфера———-;
smesh macro b64, bx
b64:;смещаем разряды слева направо
inc bx
mov al, [bx]; берем правый
dec bx
mov [bx], al;перекладываем левее
inc bx
loop b64
endm
;——считывание символа операции—————-;
read_klmacro
print string2;макрос вывода строки «Выберете оперецию: «
xor ax, ax;обнуляем регистры
xor dx, dx
mov ah, 01h;функция считывания символа с клавиатуры (с эхо)
int 21h;вызов прерывания 21h
cmp al, '+';сравнение с '+'
je op01;если равны — значит складываем
cmp al, '-';сравнение с '-'
je op02;если равны — вычитаем
cmp al, '*';сравнение с '*'
je op03;если равны — умножаем
cmp al, '/';сравнение с '/'
je op04;если равны — делим
cmp al, 'q';сравнение с 'q'
je Quit;выходим из программы
cmp al, 'Q';сравнение с 'Q'
je Quit;выходим из программы
jmp met_op;если введен другой символ,
endm;то игнорируем и ждем нового (снова в макрос)
;—————————————————————;
;—————————————————————;
.model small
.stack 100h
.data
string_1db0,13,'Enter the number: $'
string_2db0,13,'Select operation: $'
string_3db0,13,'Entered an incorrect number. Try again. $'
string_4db10,13,'Incorrect operation. a
string_5db0Dh, 0Ah,'$';перевод каретки
string_6db10,13,'Result operation: $'
string_7db10,13,'Incorrect operation. b=0. Try again. $'
chastnoedq8;результат операции деления
chalengtdw?
bufer_01dq8;первое число
numbe_01dq8;первое число, начиная с правого края
blength1dw?
bufer_02dq8;второе число
numbe_02dq8;второе число, начиная с правого края
blength2dw?
bufer_03dq8 ;буфер для вывода
blength3dw?
bufer_04dq8;буфер для деления
blength4dw?
bufer_05dq2 dup (0);выделение памяти
flagdb0;если 1е меньше, то флаг равен 1
flag2db0;если результат вычитания 0, то флаг равен 1
flag01db0;знак 1го числа (2B='+', 2D='-')
flag02db0;знак 2го числа
flag03db0;знак результата
.code
start:
mov ax, @data;запись в ax адреса на сегмент данных
mov ds, ax;инициализация сегмента данных
mov es, ax;инициализация сегмента доп. данных
call clear;вызов процедуры очистки экрана
b111:
lea di, numbe01+1
lea si, numbe02+1
call och_bufer
lea di, bufer03+1
lea si, bufer04+3
call och_bufer
lea di, chastnoe
lea si, bufer04+11
call och_bufer
b11:
znak flag01, b11, b12;считываем знак 1го числа
read_b bufer01;считываем строку в буфер1
b13:
znak flag02, b13, b14;считываем знак 2го числа
read_b bufer02;считываем строку в буфер2
perep bufer01, numbe01, a28, b23, b24;макрос переноса в правую часть 1го числа
perep bufer02, numbe02, a29, b25, b26;макрос переноса в правую часть 2го числа
;сделаем, чтобы первое всегда было больше
lea di, numbe01+2;первое число
lea si, numbe02+2;второе число
call srav;вызываем процедуру сравнения
mov dx, [bx]; проверка флага
cmp dl, byte ptr 00;a>b
je b00
perem b18;b>a
;необходимо помменять местами знаки
lea di, flag01;первое число
lea si, flag02;второе число
mov al, [di]
mov bl, [si]
mov [di], bl
mov [si], al
b00:;теперь всегда a>b
met_op:read_kl;макрос считывания символа операции
Quit:
mov ax, 4c00h;стандартное завершение программы
int 21h
op01:;сложение с учетом знаков
call zp_znak
cmp al, byte ptr 56h;оба числа положительные (2B+2B)
je b01
cmp al, byte ptr 5Ah;оба числа отрицательные (2D+2D)
je b02
cmp dl, byte ptr 2Bh;одно отрицательное (2D), второе (в dl первый знак. если он положительный, то переход)
je b03
;если 1й отрицательный, то переход на b04
b04:
lea di, numbe01+8;получаем адрес 1го числа, начиная с правого разряда
call p_vich;-a+b
set_flag 2Dh, b07
b01:call p_sloj;a+b
set_flag 2Bh, b07
b02:call p_sloj;-a+(-b)
set_flag 2Dh, b07
b03:lea di, numbe01+8;получаем адрес 1го числа, начиная с правого разряда
call p_vich;a+(-b)
set_flag 2Bh, b07
b07:
lea bx, bufer03;адрес на буфер в bx
jmp callvivod
op02:;вычитание с учетом знака
call zp_znak
cmp al, byte ptr 56h;оба числа положительные (2B+2B)
je b03
cmp al, byte ptr 5Ah;оба числа отрицательные (2D+2D)
je b04
cmp dl, byte ptr 2Bh;одно отрицательное (2D), второе
je b01
jmp b02;одно отрицательное, первое
op04: jmp op042
op03:
call zp_znak
cmp al, byte ptr 58h;числа с разным знаком (2D+2B)
je b06
set_flag 2Bh, b05;знак вывода +
b06:
set_flag 2Dh, b05;знак вывода -;умножение
b05:call p_umno;вызов процедуры умножения
jmp callvivod2
op042:
call zp_znak
cmp al, byte ptr 58h;числа с разным знаком (2D+2B)
je b16
set_flag 2Bh, b17;знак вывода +
b16:
set_flag 2Dh, b17;знак вывода -;деление
b17:call p_dele;вызов процедуры умножения
lea bx, chastnoe;адрес на буфер в bx
;jmp callvivodпереходим
callvivod:;вывод после сложения+вычитания
print string6;макрос вывода строки «Результат операции: «
call vivod;процедура вывода числа из bufer03
print string5;макрос вывода строки (переноса каретки)
jmp b111
callvivod2:;вывод после умножения
print string6;макрос вывода строки «Результат операции: «
call vivod2;процедура вывода числа из bufer04
print string5;макрос вывода строки (переноса каретки)
jmp b111
;
;теперь необходимо обнулить ячейки в памяти (буферы 1,2,3) — скорее всего процедурой
;и прыгнуть на метку, которая после вызова процедуры очистки экрана
;———————процедуры—————————-;
;——процедура очистки экрана———————;
clear proc
mov ah, 00h;установка видеорежима дисплея
mov al, 03h;номер видеорежима
int 10h;вызов прерывания 10h
ret
clear endp
;——сравнение чисел, а и б————————-;
sravproc
mov cx, 7
lea bx, flag
mov [bx], byte ptr 00;обнуляем значение флага
a35:
mov al, [di]
cmp al, [si]
jg a36;если 1е больше, то переход
jz a37;если равны
;lea bx, flag
mov [bx], byte ptr 01
jmp a36;на выход
a37:
inc di
inc si
loop a35
a36:
ret
srav endp
;——процедура записи знаков———————-;
zp_znakproc
lea di, flag01
lea si, flag02
mov al, [di]
mov dl, al;сохраним знак 1го числа
add al, [si]
ret
zp_znak endp
;——очистка буферов———————————-;
och_bufer proc
mov cx, 8
b20:
mov [di], byte ptr 00
mov [si], byte ptr 00
inc di
inc si
loop b20
ret
och_bufer endp
;——сложение———————————————;
p_sloj proc
clc;очистка флага переноса
lea di, numbe01+8;получаем адрес 1го числа, начиная с правого разряда
lea si, numbe02+8;получаем адрес 2го числа, начиная с правого разряда
lea bx, bufer03+8;получаем адрес, по которому запишем результат, начиная с правого разряда
mov cx, 7;в счетчик заносим длину числа в байтах
a20:
xor ax, ax;очистим регистр AH
mov al, [di]; загрузим ASCII-байт
adc al, [si] ;сложение (с переносом)
aaa;коррекция для ASCII
add [bx], al;сохранение суммы
dec bx
add [bx], ah;добавляем перенос
dec si
dec di
loop a20;зациклим
mov [bx], ah;сохраним перенос
ret
p_sloj endp
;——вычитание——————————————-;
p_vich proc
clc;очистка флага переноса
lea bx, bufer03+8;получаем адрес, по которому запишем результат, начиная с правого разряда
lea si, numbe02+8;получаем адрес 2го числа, начиная с правого разряда
mov cx, 7;в счетчик заносим длину числа в байтах
a22:
mov ah, 00;очистим регистр AH
mov al, [di]; загрузим ASCII-байт
sbb al, [si] ;вычитание (с заемом)
aas;коррекция для ASCII
mov [bx], al;сохранение суммы
dec si
dec di
dec bx
loop a22;зациклим
mov [bx], ah;сохраним перенос
ret
p_vich endp
;——умножение——————————————-;
p_umno proc
lea bx, numbe02+8;записываем множитель в bx
mov cx, 7;количество циклов для умножения__________________сделать более динамичным (для исходного числа символов)(дальше еще цикл=))
a24:;цикл призванный менять числа-множители (те цифры во втором буфере)
lea si, numbe01+8;получаем адрес 1го числа — множимое
lea di, bufer04+8;получим адрес на буфер необходимый для хранения промежуточного результата (эти результаты суммируем со сдвигом)
add di, cx;увеличиваем di, ччтобы не сползало (сдвиг)
mov al, [bx]
xor ah, ah
and al, 0fh;образаем тройку
mov dl, al
push cx;сохраняем в стеке счетчик, отвечающий за изменяемое число множителя
mov cx, 7
a23:
mov al, [si]; загружаем ascii-символ из 1го буфера
xor ah, ah
and al, 0fh;отнимаем тритцатку
mul dl;результат операции в ax
aam;коррекция для ascii
add al, [di]
aaa;коррекция для ASCII
mov [di], al;запись в память младшей части
dec di;для записи переноса
mov al, ah
xor ah, ah
add al, [di]; запись в память старшей части
aaa
mov [di], al
push di;сохраняем в стек di
a40:;расчет переноса
cmp ah, 00h;тк в нам необх в 10ой, то переносим все лишнее
jz a39;переходим если нет переноса в самый конец
dec di
mov al, ah
xor ah, ah
add al, [di]
aaa
mov [di], al
jmp a40
a39:
xor ax, ax
dec si
pop di;забираем из стека di
loop a23
pop cx
dec bx
loop a24
ret
p_umno endp
;——деление———————————————-;
p_dele proc
xor dx, dx;счетчик, необходим далее
push dx
lea di, numbe01+1;первое число оооохххх
lea si, numbe02+1;второе число оооохххх
mov cx, 8
nuli a78, a69,a70;макрос проверки, на 00 и 30h
print string7;делитель нулевой, выходим (некорекктные данные, b равно 0)
print string5;макрос вывода строки (переноса каретки)
ret
a70:
lea di, numbe01;первое число оооохххх
lea si, numbe02
call srav;процедура сравнения двух чисел
mov dx, [bx]; проверка флага
cmp dl, byte ptr 01;флаг — 1? тогда выходим
jne a68;не равно 1, 1е больше, значит выполняем деление
print string4;макрос вывода строки (некорректная операция)
print string5;макрос вывода строки (переноса каретки)
ret
a68:
;——сравнение чисел поразрядно
;сравнение 1го разряда делимого с делителем
lea di, numbe01+2;первое число оооохххх
lea bx, bufer04+8;часть первого числа
mov al, [di]; записываем в al крайний левый разряд первого числа
mov [bx], al;хаписываем в [bx] в крайнюю правую позицию
a73:
lea di, bufer04+2;первое число
lea si, numbe02+2;второе число
call srav;процедура сравнения двух чисел
mov dx, [bx]; проверка флага
cmp dl, byte ptr 01;флаг — 1? тогда выходим
jne a63;не равно 1, 1е больше, значит начинаем вычитать
;——1е меньше, то плюсуем еще число в bx из di
;—-сдвиг частного [bx] внутри буфера
a65:
lea bx, bufer04+2
mov cx, 6;по итогам последний разряд делаем предпоследним разрядом
jmp a64
a80: jmp a70
a64:
smesh a64, bx;макрос смещения строки
;запись левого разряда di в правый разряд bx
pop dx
inc dx;какой по счету разряд делимого переносим в «часть делимого»
push dx;счетчик
lea di, numbe01+2;изначальное частное (начнем со второго, тк первое уже юзаем) — таким же сдвигом пользуемся!!!
add di, dx;прибавляем к адресу смещение из счетчика
lea bx, bufer04+8;в правый разряд записываем новый разряд
lea si, flag2
mov al, [di]
mov [bx], al
cmp al, 30h;новый разряд 0?
jnz a99;если не ноль, то продолжаем считать
mov cx, [si]
cmp cl, byte ptr 01;если флаг 0, то результат вычитание ненулевой, прод считать
jnz a99
lea di, chastnoe+2;запись в последний разряд нового разряда частного
mov cx, 7;по итогам последний разряд заполнен мусором
xor dl, dl
jmp a61 ;счетчик для частного ноль и запишем его в конец
a99:
mov [si], byte ptr 00;обнулим флаг2
lea si, bufer04+2
mov cx, 7
a90:
cmp dx, 7
jne a73
pop dx;достаем лишнее из стека
ret;закончили деление, выходим из процы деления
a63:
;——если делимое [bx] больше делителя [si], то вычитаем пока это условие верно—————;
xor dx, dx;обнуляем и далее используем как счетчик
a67:
lea di, bufer04+8;1й параметр, необходимый для процедуры
call p_vich;ВЫЧИТАНИЕ
inc dx;в качестве счетчика (увеличение частного) используем dx
push dx
;——перемещаем результат из bufer03 в bufer04——-;
lea di, bufer03+2
lea si, bufer04+2
mov cx, 7
a66:
mov al, [di]
or al, 30h;добавим тройку!
mov [si], al
mov [di], byte ptr 00;очищаем bufer03+1
inc di
inc si
loop a66
lea si, bufer04+2;стираем лидирующие нули
mov cx, 7
a74:
mov al, [si]
cmp al, 30h;сравниваем с нулем
jne a75;если не ноль, то выводим
mov [si], byte ptr 00;очищаем bufer03+1
inc di
inc si
loop a74
a75:
cmp cx, 0000h;значит стирали лидирующие нули до предела=>все нули
jnz a98
lea si, flag2
mov [si], byte ptr 01;установка флага, если результат вычитания 0
a98:
;——————————————————————————;
;——сравниваем после вычитание, делимое больше?——-;
lea di, bufer04+2;первое число
lea si, numbe02+2;второе число
call srav;процедура сравнения двух чисел
mov dx, [bx]; проверка флага
cmp dl, byte ptr 01;флаг — 1? тогда выходим
pop dx
;——да! больше! вычитаем еще раз——————————;
jnz a67;если флаг=0, 1е больше, повторяем вычитание
;——если bx меньше, то сдвигаем и приписываем в частное [di] из dl (счетчик), также записываем частное и сдвигаем
lea di, chastnoe+2;запись в последний разряд нового разряда частного
mov cx, 7;по итогам последний разряд заполнен мусором
a61:
smesh a61, di
lea di, chastnoe+8;запись в последний разряд нового разряда частного
mov [di], dl
xor dl, dl
jmp a65
p_dele endp
;——вывод результата———————————;
vivod proc
lea di, flag03
mov ah, 02h
mov dl, [di]
int 21h
inc bx;1й байт — не интересует
mov cx, 8;счетчик чисел
a26:;стираем лидирующие нули
cmp byte ptr[bx], 00h;сравниваем с нулем
jne a21;если не ноль, то выводим
mov byte ptr[bx], 20h;если ноль, заменяем пробелом
inc bx
loop a26
cmp cl, byte ptr 00h;продолжаем уменьшать счетчик
jne a21
lea bx, bufer03+3;адрес на буфер в bx
mov cx, 1
a21:
or [bx], 3030h;для вывода в 10ом формате
mov ah, 02h;функция вывода символа
mov dl, [bx]; в dl выводимый символ
int 21h;вызов прерывания 21h
inc bx;следующая ячейка
loop a21;зациклим
ret
vivod endp
;——вывод результата-умножения——————-;
vivod2 proc
lea di, flag03
mov ah, 02h
mov dl, [di]
int 21h
lea bx, bufer04+3;адрес на буфер в bx
mov cx, 13;счетчик чисел
a33:;стираем лидирующие нули
cmp byte ptr[bx], 00h;сравниваем с нулем
jne a21;если не ноль, то выводим
mov byte ptr[bx], 20h;если ноль, заменяем пробелом
inc bx
loop a33
cmp cl, byte ptr 00h;продолжаем уменьшать счетчик
jne a25
lea bx, bufer04+3;адрес на буфер в bx
mov cx, 1
a25:
or [bx], 3030h;для вывода в 10ом формате
mov ah, 02h;функция вывода символа
mov dl, [bx]; в dl выводимый символ
int 21h;вызов прерывания 21h
inc bx;следующая ячейка
loop a25;зациклим
ret
vivod2 endp
;—————————————————————;
end start