1. Вывод двоичного кода числа, записанного в регистр DH.
Методика выполнения.
Нужно последовательно проанализировать биты числа. В данной работе ограничимся байтом, который будем хранить в DH. Если бит нулевой (сброшен), то нужно вывести '0', если установлен, то '1'.
Алгоритм решения задачи:
проанализировать значение одного бита;
вывести значение бита;
перейти к следующему биту. И так 8 раз (БАЙТ!) - ЦИКЛ
Анализ бита: При анализе значения программисты обычно используют команду TEST, но в данной лабораторной работе мы будет использовать следующую команду SHL
Команда SHL осуществляет сдвиг влево всех битов операнда. Старший бит операнда поступает в флаг CF. Если команда записана в формате
SHL операнд, 1
сдвиг осуществляется на 1 бит. В младший бит операнда загружается 0. Если команда записана в формате
SHL операнд,CL
сдвиг осуществляется на число битов, указанное в регистре-счетчике CL, при этом в процессе последовательных сдвигов старшие биты операнда, пройдя через флаг CF, теряются, а младшие заполняются нулями
В качестве операнда команды SHL можно указывать любой регистр (кроме сегментного) или ячейку памяти размером, как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение.
Каждый сдвиг влево эквивалентен умножению знакового числа на 2, поэтому команду SHL удобно использовать для возведения операнда в степень 2.
Команда воздействует на флаги OF, SF, ZF, PF и CF.
Прореагировать на значение флага можно с помощью команды
JNC <метка>
Осуществляется переход на метку, если флаг CF равен нулю, иначе выполняется команда, непосредственно идущая после команды.
Пример №1.1
. model tiny | ; модель памяти, в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov DH,<55> | ; заносим в регистр dh - любой ASCII-код символа |
mov AH,2 | ; помещаем номер функции DOS "вывод строки (2)" в регистр АН. |
mov CX,8 | ; инициализация переменной цикла |
@1: mov DL,'0' | ; заносим в DL код символа '0' |
shl DH, 1 | ; сдвиг на 1 бит |
jnc @2 | ; переход, если '0' |
inc DL | ; используем тот факт, что код символа '1' на единицу больше кода символа '0' |
@2: int 21h | ; вызов прерывания DOS - вызов символа; |
LOOP @1 | ; переходим на метку @1 |
int 21h | ; вызов прерывания DOS - вызов символа; |
end begin | ; метка окончания кода программы |
Замечание: в описанном способе анализа значение исходного числа теряется. Иначе следует использовать команду ROL, но 8 раз для байта.
2. Вывод значения байта в шестнадцатеричной системе счисления
2.1 Методика выполнения.
Алгоритм решения задачи:
Допустим, что байт, значение которого нужно вывести, находится в регистре DH, и имеется таблица символов "0123456789ABCDEF". Байт состоит из двух шестнадцатеричных цифр. С учетом этого задачу можно решить так: нужно вывести на экран два символа из этой таблицы. Сначала - символ с номером, равным старшему полубайту числа, а потом с номером, равным младшему полубайту.
Для решения задачи нужно решить две небольшие проблемы:
Записать в AL символ с нужным номером. Воспользуемся регистровым косвенным режимом адресации со смещением. Для этого значение каждого полубайта следует записывать в BX;
Записать в BX значение полубайта.
Простейший способ решения задачи.
Пример №2.1
. model tiny | ; модель памяти, в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov dh, 10 | ; заносим в регистр dh число 10 |
mov bl, dh | ; заносим в регистр bl число 10 |
xor bh, bh | ; Обнуление вх |
and bl, 0F0h | ; осуществляем логическое (побитовое) умножение dh на 0f0h. |
shr bl, 4 | ; сдвиг в право на 4 бита |
mov al, table [bx] | ; заносим в регистр al значение строки данных |
int 29h | ; вызов прерывания DOS - вызов символа |
mov bl, dh | ; заносим в регистр bl значение регистра dh |
and bl, 0Fh | ; осуществляем логическое (побитовое) умножение dh на 0fh. |
mov al, table [bx] | ; заносим в регистр al значение строки данных |
int 29h | ; вызов прерывания DOS - вызов символа; |
mov al, 13 | ; заносим в регистр al число 13 |
int 29h | ; вызов прерывания DOS - вызов символа; |
mov al, 10 | ; заносим в регистр al число 10 |
int 29h | ; вызов прерывания DOS - вызов символа |
ret | ; функция DOS "завершить программу" |
table db '0123456789ABCDEF' | ; cтрока с содержащая выводимые данные. |
end begin | ; метка окончания кода программы |
Алгоритм решения задачи:
Будем считать, что байт, значение которого нужно вывести, находится в регистре DH. Однако теперь применим другой способ вывода символа цифры на экран: используем тот факт, что коды символов, обозначающих цифры, отличаются от них на 30h. Но проблема здесь другая: заранее не известно, сколько цифр нужно отобразить, одну или три. Байт может принимать значение от 0 до 255. И есть еще одна проблема. При записи числа с применением позиционной системы записи в некоторой системе счисления поступают следующим образом: вычисляют и записывают остатки от деления числа на основание системы. Так поступают до тех пор, пока частное от деления не станет равным нулю. Затем остатки выписывают в порядке, обратном тому, как они получены.
Пример:
число = 251.
Делим на 10. Частное 25, остаток "1".
Делим на 10. Частное 2, остаток "5".
Делим на 10. Частное 0, остаток "2".
Нужно вывести на экран "2", "5", "1".
Задача решается с использованием стека программы. Остатки будем помещать в стек программы с помощью оператора PUSH. Одновременно будем подсчитывать число остатков, помещенных в стек. Счетчик - CX. Потом его используем для организации цикла, в котором будем извлекать остатки из стека оператором POP. Стек организован таким образом, что оператор POP извлекает последнее слово, которое было помещено туда оператором PUSH. Отметим, что оператор PUSH помещает в стек слово (WORD) или двойное слово (DWORD). Аналогично работает и оператор POP
0 комментариев