Выполнение арифметических операций над числами с фиксированной запятой
Цифра разряда делителя равна нулю. Удаление ведущих нулей в частном. Делимое и делитель не равны нулю. Вывод приглашения ввода делителя. Вывод приглашения ввода делимого. Return: popa ;восстановление регистров. Pusha ;сохранение регистров в стеке. Lea bx, sx ;вх — указывает на остаток. Удаление ведущих нулей делителя. Jmp near ptr again ;деление продолжается. Si — на младший разряд делимого. Jmp… Читать ещё >
Выполнение арифметических операций над числами с фиксированной запятой (реферат, курсовая, диплом, контрольная)
Цель: ознакомиться с командами арифметических операций, вводом данных с клавиатуры и выводом данных на экран.
Задание: написать программу ввода с клавиатуры двух чисел в 9-ричной системе счисления размером с слово, выполнения над ними деления и вывода результата в исходной системе счисления. Программа должна предусматривать контроль вводимой информации, контроль диапазона чисел и результата операции (переполнение, невозможность деления).
Программа:
;—————-ЛАБОРАТОРНАЯ РАБОТА № 3
.MODEL SMALL
.STACK 100H
.186
.DATA
S1 DB 'ВВЕДИТЕ ДЕЛИМОЕ В ДЕВЯТИРИЧНОЙ СИСТЕМЕ'
DB ' СЧИСЛЕНИЯ (ОТ -48 848 ДО 1О8806): ', 10,13,'$'
S2 DB 'ВВЕДИТЕ ДЕЛИТЕЛЬ В ДЕВЯТИРИЧНОЙ СИСТЕМЕ'
DB ' СЧИСЛЕНИЯ (ОТ -48 848 ДО 1О8806): ', 10,13,'$'
S3 DB 'НЕВЕРНАЯ ЗАПИСЬ ЧИСЛА В ДЕВЯТИРИЧНОЙ'
DB ' СИСТЕМЕ СЧИСЛЕНИЯ ИЗ ЗАДАННОГО ДИАПАЗОНА.','$'
S4 DB 'ДЕЛЕНИЕ НЕВОЗМОЖНО: ДЕЛИТЕЛЬ РАВЕН НУЛЮ.','$'
S5 DB 'ДЕЛЕНИЕ НЕВОЗМОЖНО: ДЕЛИТЕЛЬ БОЛЬШЕ ДЕЛИМОГО.','$'
S6 DB 'ОСТАТОК: ', 10,13,'$'
S7 DB 'ЧАСТНОЕ: ', 10,13,'$'
L DB '48 848' ;МИНИМАЛЬНОЕ ЧИСЛО
H DB '108 806' ;МАКСИМАЛЬНОЕ ЧИСЛО
SX DB 12 DUP ('x') ;ДЕЛИМОЕ
SY DB 12 DUP ('y') ;ДЕЛИТЕЛЬ
SZ DB 8 DUP ('0'),'$' ;ЧАСТНОЕ
.CODE
BEGIN: MOV AX, @DATA
MOV DS, AX
;—————-ОЧИСТКА БУФЕРА КЛАВИАТУРЫ
START: CLI ;ЗАПРЕТ ПРЕРЫВАНИЙ
SUB AX, AX
MOV ES, AX
MOV AL, ES:[41AH]
MOV ES:[41CH], AL
STI ;РАЗРЕШЕНИЕ ПРЕРЫВАНИЙ
;—————-ОЧИСТКА ЭКРАНА
CLD
MOV AX, 0B800H
MOV ES, AX
MOV DI, 0
MOV AL, 32
MOV AH, 7
MOV CX, 2000
REP STOSW
;—————-УСТАНОВКА КУРСОРА В ЛЕВЫЙ ВЕРХНИЙ УГОЛ ЭКРАНА
MOV AH, 2 ;НОМЕР ФУНКЦИИ
MOV BH, 0 ;НОМЕР СТРАНИЦЫ
MOV DH, 0 ;СТРОКА
MOV DL, 0 ;СТОЛБЕЦ
INT 10H ;ПОЗИЦИОНИРОВАНИЕ КУРСОРА
;—————-ВЫВОД ПРИГЛАШЕНИЯ ВВОДА ДЕЛИМОГО
LEA DX, S1
MOV AH, 9
INT 21H
;—————-ВВОД ДЕЛИМОГО
LEA DX, SX
MOV BX, DX
MOV [BX], BYTE PTR 9 ;ПРЕДПОЛАГАЕМАЯ ДЛИНА СТРОКИ
MOV AH, 0AH
INT 21H
;—————-УСТАНОВКА КУРСОРА
MOV AH, 2 ;НОМЕР ФУНКЦИИ
MOV BH, 0 ;НОМЕР СТРАНИЦЫ
MOV DH, 2 ;СТРОКА
MOV DL, 0 ;СТОЛБЕЦ
INT 10H ;ПОЗИЦИОНИРОВАНИЕ КУРСОРА
;—————-ПРОВЕРКА ПРАВИЛЬНОСТИ ВВОДА ДЕЛИМОГО
LEA DX, SX
MOV BX, DX
CALL CONTROL ;ПРОВЕРКА ПРАВИЛЬНОСТИ ВВОДА
MOV AL, [BX]
CMP AL, '0'
JE ZERO1 ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
JMP NEAR PTR DELITEL
ZERO1: LEA DX, S3
MOV AH, 9
INT 21H
;===========ОЖИДАНИЕ НАЖАТИЯ КЛАВИШИ
MOV AH, 7
INT 21H
JMP NEAR PTR START
;—————-ВЫВОД ПРИГЛАШЕНИЯ ВВОДА ДЕЛИТЕЛЯ
DELITEL: LEA DX, S2
MOV AH, 9
INT 21H
;—————-ВВОД ДЕЛИТЕЛЯ
INPUT: LEA DX, SY
MOV BX, DX
MOV [BX], BYTE PTR 9 ;ПРЕДПОЛАГАЕМАЯ ДЛИНА СТРОКИ
MOV AH, 0AH
INT 21H
;—————-УСТАНОВКА КУРСОРА
MOV AH, 2 ;НОМЕР ФУНКЦИИ
MOV BH, 0 ;НОМЕР СТРАНИЦЫ
MOV DH, 4 ;СТРОКА
MOV DL, 0 ;СТОЛБЕЦ
INT 10H ;ПОЗИЦИОНИРОВАНИЕ КУРСОРА
;—————-ПРОВЕРКА ПРАВИЛЬНОСТИ ВВОДА ДЕЛИТЕЛЯ
LEA DX, SY
MOV BX, DX
CALL CONTROL ;ПРОВЕРКА ПРАВИЛЬНОСТИ ВВОДА
CMP [BX], BYTE PTR '0'
JE ZERO2 ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
JMP NEAR PTR OK
ZERO2: LEA DX, S3
MOV AH, 9
INT 21H
;===========ОЖИДАНИЕ НАЖАТИЯ КЛАВИШИ
MOV AH, 7
INT 21H
;—————-ОЧИСТКА БУФЕРА КЛАВИАТУРЫ
CLI
SUB AX, AX
MOV ES, AX
MOV AL, ES:[41AH]
MOV ES:[41CH], AL
STI
;—————-ОЧИСТКА ЭКРАНА
CLD
MOV AX, 0B800H
MOV ES, AX
MOV DI, 480
MOV AL, 32
MOV AH, 7
MOV CX, 480
REP STOSW
;—————-УСТАНОВКА КУРСОРА
MOV AH, 2 ;НОМЕР ФУНКЦИИ
MOV BH, 0 ;НОМЕР СТРАНИЦЫ
MOV DH, 3 ;СТРОКА
MOV DL, 0 ;СТОЛБЕЦ
INT 10H ;ПОЗИЦИОНИРОВАНИЕ КУРСОРА
JMP NEAR PTR INPUT
;—————-УСТАНОВКА КУРСОРА
OK: MOV AH, 2 ;НОМЕР ФУНКЦИИ
MOV BH, 0 ;НОМЕР СТРАНИЦЫ
MOV DH, 4 ;СТРОКА
MOV DL, 0 ;СТОЛБЕЦ
INT 10H ;ПОЗИЦИОНИРОВАНИЕ КУРСОРА
;—————-ПРОВЕРКА ВОЗМОЖНОСТИ ДЕЛЕНИЯ
LEA BX, SX
CALL CTRL0
MOV AH, [BX]
LEA BX, SY
CALL CTRL0
MOV AL, [BX]
CMP AL, '0'
JE NULL
JMP N_NULL
;—————-ДЕЛИТЕЛЬ РАВЕН НУЛЮ
NULL: LEA DX, S4
MOV AH, 9
INT 21H
JMP NEAR PTR ENDPROG
;—————-ДЕЛИТЕЛЬ НЕ РАВЕН НУЛЮ
N_NULL: CMP AH, '0'
JNE DELENIE
;—————-ДЕЛИМОЕ РАВНО НУЛЮ
LEA DX, S7
MOV AH, 9
INT 21H
LEA BX, SZ
MOV [BX], BYTE PTR '0'
INC BX
MOV [BX], BYTE PTR 10
INC BX
MOV [BX], BYTE PTR 13
INC BX
MOV [BX], BYTE PTR '$'
LEA DX, SZ
MOV AH, 9
INT 21H
LEA DX, S6
MOV AH, 9
INT 21H
LEA DX, SZ
MOV AH, 9
INT 21H
JMP NEAR PTR ENDPROG
;—————-ДЕЛИМОЕ И ДЕЛИТЕЛЬ НЕ РАВНЫ НУЛЮ
DELENIE: LEA SI, SX
LEA DI, SY
CALL COMPARE
CMP [SI], BYTE PTR 1
JE POSSIBLE
;—————-ДЕЛИТЕЛЬ БОЛЬШЕ ДЕЛИМОГО
LEA DX, S5
MOV AH, 9
INT 21H
JMP NEAR PTR ENDPROG
;—————-НАЧИНАЕТСЯ ДЕЛЕНИЕ
POSSIBLE: MOV BX, 7 ;BX — ИНДЕКС ДЛЯ ЧАСТНОГО
;—————-В СХ — ЧИСЛО РАЗРЯДОВ ДЕЛИТЕЛЯ
AGAIN: MOV CL, SY[1] ;CX — ЧИСЛО РАЗРАДОВ ДЕЛИТЕЛЯ
MOV CH, 0
;—————-DI — НА МЛАДШИЙ РАЗРЯД ДЕЛИТЕЛЯ
MOV DI, CX ;DI — ИНДЕКС ДЛЯ ДЕЛИТЕЛЯ
INC DI
;—————-УДАЛЕНИЕ ВЕДУЩИХ НУЛЕЙ ДЕЛИТЕЛЯ
MOV SI, 2 ;SI — ИНДЕКС ДЛЯ ДЕЛИМОГО
MOV AL, SY[SI]
CMP AL, '-'
JNE BEFORE_C1
INC SI
DEC CX
BEFORE_C1: MOV AL, SY[SI]
CMP AL, '0'
JE SS1
JMP LBLL
SS1: INC SI
DEC CX
JMP BEFORE_C1
;—————-SI — НА МЛАДШИЙ РАЗРЯД ДЕЛИМОГО
LBLL: MOV AL, SX[1]
CBW ;АН — ДЛЯ ЗАПИСИ ПЕРЕНОСА
MOV SI, AX
INC SI
;—————-НАЧАЛО ЦИКЛА ДЕЛЕНИЯ
;===========СРАВНЕНИЕ ЦИФР РАЗРЯДА ДЕЛИМОГО И ДЕЛИТЕЛЯ
C1: MOV AL, SX[SI]
CMP AL, SY[DI]
JAE NEXT
;===========ЦИФРА ДЕЛИМОГО МЕНЬШЕ ЦИФРЫ ДЕЛИТЕЛЯ
ADD AL, 9 ;ЗАЁМ ЕДИНИЦЫ
SUB AL, SY[DI] ;ВЫЧИТАНИЕ
ADD AL, '0' ;ПЕРЕВОД ЦИФРЫ В ЕЕ КОД
SUB AL, AH ;ВЫЧИТАНИЕ ПЕРЕНОСА
MOV SX[SI], AL ;РЕЗУЛЬТАТ — НА МЕСТО РАЗРЯДА ДЕЛИМОГО
MOV AH, 1 ;ЗАПИСЬ ЗАЁМА
JMP NEAR PTR DECREM ;НА КОНЕЦ ЦИКЛА
;===========ЦИФРА ДЕЛИМОГО БОЛЬШЕ ЦИФРЫ ДЕЛИТЕЛЯ
NEXT: SUB AL, SY[DI] ;ВЫЧИТАНИЕ
SUB AL, AH ;ВЫЧИТАНИЕ ПЕРЕНОСА
MOV AH, 0 ;ЗАЁМА НЕТ
ADD AL, '0' ;ПЕРЕВОД ЦИФРЫ В ЕЕ КОД
MOV SX[SI], AL ;РЕЗУЛЬТАТ — НА МЕСТО РАЗРЯДА ДЕЛИМОГО
;—————-SI, DI — НА БОЛЕЕ СТАРШИЙ РАЗРЯД
DECREM: DEC SI
DEC DI
LOOP C1 ;НА НАЧАЛО ЦИКЛА ДЕЛЕНИЯ
;—————-БЫЛ ЛИ ЗАЁМ ИЛИ НЕТ
CMP AH, 1
JNE SRAVN
;—————-ЗАЁМ БЫЛ
AGAIN1: CMP SX[SI], '0' ;СРАВНЕНИЕ ЦИФРЫ РАЗРЯДА С НУЛЁМ
JE C2
DEC SX[SI]
JMP SRAVN
;—————-ЦИФРА РАЗРЯДА ДЕЛИТЕЛЯ РАВНА НУЛЮ
C2: MOV SX[SI], '8'
DEC SI ;НА БОЛЕЕ СТАРШИЙ РАЗРЯД
JMP AGAIN1 ;НА СРАВНЕНИЕ ЦИФРЫ РАЗРЯДА С НУЛЁМ
;===========ФОРМИРОВАНИЕ ЧАСТНОГО
;—————-ЕСТЬ ЛИ ПЕРЕНОС ПРИ УВЕЛИЧЕНИИ ЧАСТНОГО НА ЕДИНИЦУ
SRAVN: CMP SZ[BX], '8'
JE PERENOS
;—————-ПЕРЕНОСА НЕТ
ADD SZ[BX], 1 ;УВЕЛИЧЕНИЕ ЧАСТНОГО НА ЕДИНИЦУ
MOV BX, 7 ;ВХ — НА МЛАДШИЙ РАЗРЯД
JMP DEL ;НА СРАВНЕНИЕ ДЕЛИМОГО И ДЕЛИТЕЛЯ
;—————-ПЕРЕНОС ЕСТЬ
PERENOS: MOV SZ[BX], '0' ;В ДАННЫЙ РАЗРЯД — НУЛЬ
DEC BX ;УВЕЛИЧЕНИЕ РАЗРЯДА
JMP SRAVN ;НА СРАВНЕНИЕ РАЗРЯДА С «8»
;===========СРАВНЕНИЕ ДЕЛИМОГО И ДЕЛИТЕЛЯ
DEL: LEA SI, SX
LEA DI, SY
CALL COMPARE
MOV AL, [SI]
CMP AL, 1
JNE QUIT ;ДЕЛЕНИЕ ЗАВЕРШЕНО
JMP NEAR PTR AGAIN ;ДЕЛЕНИЕ ПРОДОЛЖАЕТСЯ
;—————-ОПРЕДЕЛЕНИЕ ЗНАКА ЧАСТНОГО
QUIT: MOV AH, SX[2]
MOV AL, SY[2]
;—————-ВЫЯСНЕНИЕ ЗНАКА ДЕЛИМОГО
CMP AH, '-'
JE SX_
JMP N_SX_
;—————-ДЕЛИМОЕ — ОТРИЦАТЕЛЬНОЕ
SX_: CMP AH, AL ;СРАВНЕНИЕ ЗНАКА ДЕЛИМОГО И ДЕЛИТЕЯ
JE OUTP ;НА ВЫВОД ОСТАТКА
;—————-ДЕЛИТЕЛЬ — ПОЛОЖИТЕЛЬНЫЙ
;===========УДАЛЕНИЕ ВЕДУЩИХ НУЛЕЙ В ЧАСТНОМ
SY_: MOV BX, 0
SRCH: CMP SZ[BX], '0'
JE DALEE
JMP STOP
DALEE: INC BX
JMP SRCH
;—————-ЗАПИСЬ МИНУСА ПЕРЕД СТАРШИМ РАЗРЯДОМ ЧАСТНОГО
STOP: DEC BX
MOV SZ[BX], '-'
JMP OUTP ;НА ВЫВОД ОСТАТКА
;—————-ДЕЛИМОЕ ПОЛОЖИТЕЛЬНОЕ
N_SX_: CMP AL, '-' ;ДЕЛИТЕЛЬ ОТРИЦАТЕЛЬНЫЙ?
JE SY_ ;ЧАСТНОЕ ОТРИЦАТЕЛЬНОЕ
;—————-ВЫВОД ЧАСТНОГО
;===========ВЫВОД ОСТАТКА
;—————-ВЫВОД СТРОКИ «ОСТАТОК:»
OUTP: LEA DX, S6
MOV AH, 9
INT 21H
;ЗАПИСЬ В КОНЕЦ ОСТАТКА СИМВОЛОВ 10, 13 И «$»
MOV BH, 0
MOV BL, SX[1]
ADD BX, 2 ;ВХ — ЗА МЛАДШИЙ РАЗРЯД
MOV SX[BX], 10
INC BX
MOV SX[BX], 13
INC BX
MOV SX[BX], '$'
;—————-УДАЛЕНИЕ ВЕДУЩИХ НУЛЕЙ ОСТАТКА
MOV AH, '0'
LEA BX, SX ;ВХ — УКАЗЫВАЕТ НА ОСТАТОК
INC BX
INC BX
MOV AL, [BX]
CMP AL, '-'
JE MN
JMP N_MN
MN: MOV AH, '-'
INC BX
N_MN: MOV AL, [BX]
CMP AL, '0'
JE EQ1
JMP NEQ1
EQ1: INC BX
JMP N_MN
NEQ1: MOV AL, [BX]
DEC BX
CMP AL, 10
JE N_NUL
MOV [BX], AH
CMP AH, '-'
JE EQQ
JMP NEQQ
EQQ: MOV DX, BX
JMP LBL
NEQQ: INC BX
MOV AL, [BX]
CMP AL, 10
JE NUL
JMP N_NUL
NUL: DEC BX
N_NUL: MOV DX, BX
LBL: MOV AH, 9
INT 21H
;===========ВЫВОД ЧАСТНОГО
LEA DX, S7
MOV AH, 9
INT 21H
LEA BX, SZ
Q: MOV AL, [BX]
CMP AL, '0'
JE SM3
JMP OUTPUT
SM3: INC BX
JMP Q
OUTPUT: MOV DX, BX
MOV AH, 9
INT 21H
;—————-ВЫХОД ИЗ ПРОГРАММЫ
ENDPROG: MOV AH, 4CH
INT 21H
;===========ПРОЦЕДУРА CONTROL — ЧИСЛО ДЕВЯТИРИЧНОЕ?
CONTROL PROC
PUSHA ;СОХРАНЕНИЕ РЕГИСТРОВ В СТЕКЕ
MOV BX, DX
INC BX
MOV AL, [BX]
MOV AH, 0
MOV CX, AX
;—————-ЯВЛЯЕТСЯ ЛИ СТРОКА ПУСТОЙ?
CMP AL, 0
JE ERR1 ;ЯВЛЯЕТСЯ
;—————-ПРОВЕРКА ДЛИНЫ СТРОКИ
CMP AL, 6
JA ERR1 ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
INC BX
MOV AH, [BX]
CMP AH, '-'
JE MINUS
JMP NEAR PTR FOR1
MINUS: INC BX ;ЧИСЛО ОТРИЦАТЕЛЬНОЕ
DEC CX
;—————-ВВЕДЕННОЕ ЧИСЛО ДЕВЯТИРИЧНОЕ?
FOR1: MOV AH, [BX]
CMP AH, '9'
JB N1
ERR1: JMP NEAR PTR ERROR ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
N1: CMP AH, '0'
JB ERR1 ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
INC BX
LOOP FOR1
MOV [BX], BYTE PTR '$' ;ДЛЯ ВЫВОДА СТРОКИ
CMP AL, 6
JNE RETURN ;ЕСЛИ ДЛИНА ЧИСЛА МЕНЬШЕ 6
MOV BX, DX
INC BX
MOV AH, 0
MOV CX, AX
INC BX
MOV AH, [BX]
CMP AH, '-'
JE M1 ;ЧИСЛО ОТРИЦАТЕЛЬНОЕ
LEA DI, H ;ЧИСЛО ПОЛОЖИТЕЛЬНОЕ
JMP FOR2
M1: INC BX
DEC CX
LEA DI, L
;ВХОДИТ ЛИ ЧИСЛО В ЗАДАННЫЙ ДИАПАЗОН?
FOR2: MOV AH, [BX]
CMP AH, [DI]
JA ERROR ;ЧИСЛО ВВЕДЕНО НЕВЕРНО
JB RETURN ;ЧИСЛО ВВЕДЕНО ПРАВИЛЬНО
INC BX
INC DI
LOOP FOR2
JMP RETURN
ERROR: MOV BX, DX
MOV [BX], BYTE PTR '0'
RETURN: POPA ;ВОССТАНОВЛЕНИЕ РЕГИСТРОВ
RET
CONTROL ENDP
;===========ПРОЦЕДУРА CTRL0 — ЭТО НУЛЬ?
CTRL0 PROC
PUSHA
MOV SI, 1
MOV CL, [BX+SI]
MOV CH, 0
INC SI
MOV AL, [BX+SI]
CMP AL, '-'
JE MIN
JMP CYCLE
MIN: INC SI
DEC CX
CYCLE: MOV AL, [BX+SI]
CMP AL, '0'
JNE FINISH
INC SI
LOOP CYCLE
MOV SI, 0
MOV AL, '0'
MOV [BX+SI], AL
FINISH: POPA
RET
CTRL0 ENDP
;===========ПРОЦЕДУРА COMPARE — СРАВНЕНИЕ ДВУХ ЧИСЕЛ
COMPARE PROC
PUSHA
INC SI
INC DI
MOV AH, [SI]
MOV AL, [DI]
INC SI
INC DI
CMP BYTE PTR [SI], '-'
JE NEGAT1
JMP POZIT1
NEGAT1: DEC AH
INC SI
POZIT1: CMP BYTE PTR [DI], '-'
JE NEGAT2
JMP POZIT2
NEGAT2: DEC AL
INC DI
POZIT2: MOV BL, [SI]
CMP BL, '0'
JE SM
JMP DI0
SM: INC SI
DEC AH
JMP POZIT2
DI0: MOV BL, [DI]
CMP BL, '0'
JE SM1
JMP SRAV1
SM1: INC DI
DEC AL
JMP DI0
SRAV1: CMP AH, AL
JA ABOVE
JB BELOW
JMP EQUAL
ABOVE: LEA SI, SX
MOV [SI], BYTE PTR 1
JMP NEAR PTR END1
BELOW: LEA SI, SX
MOV [SI], BYTE PTR -1
JMP NEAR PTR END1
EQUAL: MOV CL, AL
MOV CH, 0
FOR3: MOV AH, [SI]
CMP AH, [DI]
JA ABOVE
JB BELOW
INC SI
INC DI
LOOP FOR3
JMP ABOVE
END1: POPA
RET
COMPARE ENDP
END BEGIN