Цель: ознакомиться с командами арифметических операций, вводом данных с клавиатуры и выводом данных на экран. Задание: написать программу ввода с клавиатуры двух чисел в 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 21ITEL: 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 21IBLE: 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
! |
Как писать рефераты Практические рекомендации по написанию студенческих рефератов. |
! | План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом. |
! | Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач. |
! | Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты. |
! | Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ. |
→ | Виды рефератов Какими бывают рефераты по своему назначению и структуре. |