Лабораторная работа №7
Задание 1.
Напишите код, выполняющий загрузку управляющего регистра и считывание введённого с клавиатуры символа.
Для считывания символа, введённого с клавиатуры, используется прерывание DOS INT 21 функция 1. Номер функции определяется по регистру AH.
MOV AH,01
INT 21
ASCII код символа нажатой клавиши помещается в регистр AL.
Например, для введенного символа «h» AL=68h
Задание 2.
Составьте программу, записывающую в регистр AL шестнадцатеричную цифру введённую с клавиатуры.
Для введенной шестнадцатеричной цифры соответствуют три диапазона. Для получения шестнадцатеричного кода нужно из регистра AL вычесть определенное значение:
30h-39h (“0”-“9”) – вычитаем 30h
41h-46h (“A”-“F”) – вычитаем 37h (из предыдущего диапазона вычесть 7h)
61h-66h (“a”-“f”) – вычитаем 57h (из предыдущего диапазона вычесть 20h)
Соответствующая программа:
0B83:0100 B401 MOV AH,01
0B83:0102 CD21 INT 21
0B83:0104 3C46 CMP AL,46
0B83:0106 7E02 JLE 010A
0B83:0108 2C20 SUB AL,20
0B83:010A 3C39 CMP AL,39
0B83:010C 7E02 JLE 0110
0B83:010E 2C07 SUB AL,07
0B83:0110 2C30 SUB AL,30
0B83:0112 CD20 INT 20
Задание 3.
Напишите программу ввода в регистр BX двухзначного числа с клавиатуры.
Опираясь на предыдущее задание получим программу:
0B86:0100 B401 MOV AH,01
0B86:0102 CD21 INT 21
0B86:0104 3C46 CMP AL,46
0B86:0106 7E02 JLE 010A
0B86:0108 2C20 SUB AL,20
0B86:010A 3C39 CMP AL,39
0B86:010C 7E02 JLE 0110
0B86:010E 2C07 SUB AL,07
0B86:0110 2C30 SUB AL,30
0B86:0112 88C2 MOV DL,AL
0B86:0114 B104 MOV CL,04
0B86:0116 D2E2 SHL DL,CL
0B86:0118 CD21 INT 21
0B86:011A 3C46 CMP AL,46
0B86:011C 7E02 JLE 0120
0B86:011E 2C20 SUB AL,20
0B86:0120 3C39 CMP AL,39
0B86:0122 7E02 JLE 0126
0B86:0124 2C07 SUB AL,07
0B86:0126 2C30 SUB AL,30
0B86:0128 00D0 ADD AL,DL
0B86:012A 88C3 MOV BL,AL
0B86:012C CD20 INT 20
До смещения 0112 программа вычисляет код первого введенного символа; 0112-0116 – этот код сдвигается влево на 4бита (переходит в старшую цифру числа), записывается в регистре dl; 0118-0126 – ввод второй цифры. По смещению 0128 регистры al и dl складываются, получая тем самым результат, состоящий из старшей и младшей цифры.
Лабораторная работа №8
Задание 1.
Напишите процедуру, выполняющую вывод символа (код в регистре DL), и увеличение выводимого кода на 1. Разместите процедуру начиная со смещения 200.
Начиная со смещения 100 разместите программу, которая выведет на экран 14 символов начиная с цифры 2, с использованием процедуры по адресу 200. Запишите программу в файл.
Процедура вывода символа с кодом в регистре DL и увеличение этого кода на 1:
0B86:0200 B402 MOV AH,02
0B86:0202 CD21 INT 21
0B86:0204 FEC2 INC DL
0B86:0206 C3 RET
Основная программа, выводящая 14(E) символов, начиная с цифры “2” (ASCII-код 32h):
0B86:0100 B232 MOV DL,32
0B86:0102 B90E00 MOV CX,000E
0B86:0105 E8F800 CALL 0200
0B86:0108 E2FB LOOP 0105
0B86:010A CD20 INT 20
На экран был выведен ряд:
23456789:;<=>?
(См. файл E_CALL.com)
Задание 2.
Напишите программу, которая позволяет занести в стек последовательность из 10 шестнадцатеричных чисел. Используйте в качестве процедуры написанную в работе 4 программу ввода чисел.
Выведите дамп стека после выполнения ввода.
Программа будет состоять из трех частей:
(смещение 100) Основная программа – цикл с пятью итерациями, в каждой из которой дважды вызывается подпрограмма ввода одного шестнадцатеричного числа (однобайтовый формат). Перед выполнением процедур в стек запоминается значение регистра CX (номер итерации) командой PUSH CX, после возврата – вновь восстанавливается из стека POP CX. Это необходимо для того, чтобы подпрограммы не изменили текущего значения CX. Затем помещаются полученные два байта (BX) в стек – PUSH BX.
0B86:0100 B90500 MOV CX,0005
0B86:0103 51 PUSH CX
0B86:0104 E81900 CALL 0120
0B86:0107 88C7 MOV BH,AL
0B86:0109 E81400 CALL 0120
0B86:010C 88C3 MOV BL,AL
0B86:010E 59 POP CX
0B86:010F 53 PUSH BX
0B86:0110 E2F1 LOOP 0103
0B86:0112 CD20 INT 20
(смещение 120) Подпрограмма ввода двух цифр шестнадцатеричного числа и записи их в регистр AL (см. задание 3, л/р №7), а также ставит между ними пробел (для этого надо вывести символ с кодом 20h)
0B86:0120 B402 MOV AH,02
0B86:0122 B220 MOV DL,20
0B86:0124 CD21 INT 21
0B86:0126 E81700 CALL 0140
0B86:0129 88C2 MOV DL,AL
0B86:012B B104 MOV CL,04
0B86:012D D2E2 SHL DL,CL
0B86:012F E80E00 CALL 0140
0B86:0132 00D0 ADD AL,DL
0B86:0134 C3 RET
(смещение 140) Подпрограмма ввода с клавиатуры одной шестнадцатеричной цифры (результат – AL) (см. задание 2, л/р №7)
0B86:0140 B401 MOV AH,01
0B86:0142 CD21 INT 21
0B86:0144 3C46 CMP AL,46
0B86:0146 7E02 JLE 014A
0B86:0148 2C20 SUB AL,20
0B86:014A 3C39 CMP AL,39
0B86:014C 7E02 JLE 0150
0B86:014E 2C07 SUB AL,07
0B86:0150 2C30 SUB AL,30
0B86:0152 C3 RET
После запуска программы были введены 10 шестнадцатеричных чисел:
-g114
45 7d 5F 83 ca FA 00 01 99 FA
Программа завершилась нормально
Затем, чтобы получить дамп стека, необходимо узнать адрес указателя стека, и затем вывести дамп соответствующих адресов командой -d:
-r sp
SP FFEC
-D FFE0
0B86:FFE0 8A 03 FA 99 01 00 FA CA-83 5F 7D 45 08 01 00 00 ........._}E....
Как видим, программа занесла в стек все введенные значения, начиная с первого, с каждым разом адрес указателя стека уменьшался на 2 байта (ровно столько нужно, чтобы записать значение одного регистра), поэтому адрес каждого последующего значения в стеке меньше предыдущего и данные в нем записаны в обратной последовательности по логике LIFO.
(файл PUSH10.com)
