Лабораторная работа: Выполнение арифметических операций над числами с фиксированной запятой
Название: Выполнение арифметических операций над числами с фиксированной запятой Раздел: Рефераты по информатике Тип: лабораторная работа |
Цель: ознакомиться с командами арифметических операций, вводом данных с клавиатуры и выводом данных на экран. Задание: написать программу ввода с клавиатуры двух чисел в 9-ричной системе счисления размером с слово, выполнения над ними деления и вывода результата в исходной системе счисления. Программа должна предусматривать контроль вводимой информации, контроль диапазона чисел и результата операции (переполнение, невозможность деления). Программа: ;-----------ЛАБОРАТОРНАЯ РАБОТА №3 .MODEL SMALL .STACK 100H .186 .DATA S1 DB 'ВВЕДИТЕ ДЕЛИМОЕ В ДЕВЯТИРИЧНОЙ СИСТЕМЕ' DB ' СЧИСЛЕНИЯ (ОТ -48848 ДО 1О8806): ',10,13,'$' S2 DB 'ВВЕДИТЕ ДЕЛИТЕЛЬ В ДЕВЯТИРИЧНОЙ СИСТЕМЕ' DB ' СЧИСЛЕНИЯ (ОТ -48848 ДО 1О8806): ',10,13,'$' S3 DB 'НЕВЕРНАЯ ЗАПИСЬ ЧИСЛА В ДЕВЯТИРИЧНОЙ' DB ' СИСТЕМЕ СЧИСЛЕНИЯ ИЗ ЗАДАННОГО ДИАПАЗОНА.','$' S4 DB 'ДЕЛЕНИЕ НЕВОЗМОЖНО: ДЕЛИТЕЛЬ РАВЕН НУЛЮ.','$' S5 DB 'ДЕЛЕНИЕ НЕВОЗМОЖНО: ДЕЛИТЕЛЬ БОЛЬШЕ ДЕЛИМОГО.','$' S6 DB 'ОСТАТОК: ',10,13,'$' S7 DB 'ЧАСТНОЕ: ',10,13,'$' L DB '48848' ;МИНИМАЛЬНОЕ ЧИСЛО H DB '108806' ;МАКСИМАЛЬНОЕ ЧИСЛО 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 |