Скачиваний:
148
Добавлен:
11.02.2014
Размер:
108.03 Кб
Скачать

Лабораторная работа №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)