Для вывода байта в шестнадцатеричном виде определим таблицу
table db ‘0123456789ABCDEF’ в которой значение шестнадцатеричной цифры будет равно смещению относительно начала таблицы символа, служащего ASCII – кодом этого значения. Например код ‘5’ находится по адресу table1+5, код ‘E’ находится по адресу table1+0Eh, и т.д.
Воспользуемся следующей командой
xlat
без операндов, операнды которой задаются неявно:
· bx — является указателем на начала массива символов,
· al — содержит число, которое служит смещением (индексом) байта, возвращаемого в регистр al.
Для нашей таблицы table1 после команд
lea bx, table1
mov al,5
xlat
в регистре al будет находиться символ ‘5’. Подпрограмма будет выводить содержимое байта следующим образом: берется старшая тетрада байта и выводится соответствующий ей символ. Потом выводится символ, соответствующий младшей тетраде.
hex proc ;вывод dl в шестнадцатеричном виде
push dx
lea bx,table1
mov al,dl
shr al,4
xlat
mov dl,al ;вывод
mov ah,2 ;старшей
int 21h ;цифры
pop ax
and al,00001111b
xlat
mov dl,al ;вывод
mov ah,2 ;младшей
int 21h ;цифры
ret
table db ‘0123456789ABCDEF’
hex endp
Напишем теперь подпрограммы вывода содержимого слова в шестнадцатеричном виде. Воспользуемся подпрограммой hex, с помощью которой будем выводить сначала старший, а затем младший байты. Наши подпрограммы будут подсоединяться при сборке:
< 1 > title mylib.obj
< 2 > subr segment
< 3 > public display, kbin, hex, hexw, crlf
< 4 > assume cs:subr, ds:subr
< 5 > ;——подпрограммы———————
< 6 > display proc
< 7 > mov ah,2
< 8 > int 21h
< 9 > ret
< 10 > display endp
< 11 >
< 12 > kbin proc ;ввод символа
< 13 > mov ah,1 ;в регистр al
< 14 > int 21h
< 15 > ret
< 16 > kbin endp
< 17 >
< 18 > hex proc ;вывод dl в 16-ном виде
< 19 > mov ax,subr ;инициализация ds
< 20 > mov ds,ax ;на сегмент, содержащий table1
< 21 > push dx
< 22 > lea bx,table1
< 23 > mov ax,0
< 24 > mov al,dl
< 25 > shr al,4
< 26 > xlat ;преобразование
< 27 > mov dl,al ;ASCII-код цифры
< 28 > call display
< 29 > pop ax ;бывшее содержимое dx
< 30 > and al,00001111b ;младший полубайт
< 31 > xlat
< 32 > mov dl,al
< 33 > call display
< 34 > ret
< 35 > table1 db ‘0123456789ABCDEF’
< 36 > hex endp
< 37 >
< 38 > hexw proc ;вывод в 16-ном виде
< 39 > mov di,dx ;сохранить dx
< 40 > mov dl,dh ;вывод старшего байта
< 41 > call hex
< 42 > mov dx,di ;восстановить dx
< 43 > call hex ;вывод dl
< 44 > mov dl,’ ‘ ;пробел
< 45 > call display
< 46 > ret
< 47 > hexw endp
< 48 >
< 49 > crlf proc ;вывод
< 50 > mov dl,10 ;перевода
< 51 > call display ;строки и
< 52 > mov dl,13 ;возврата
< 53 > call display ;каретки
< 54 > ret
< 55 > crlf endp
subr ends
< 1 >
< 2 > end
Команда xlat обращается к таблице, имеющей адрес ds:bx, поэтому в подпрограмме hex регистр ds инициализируется. Объектный модуль mylib.obj получается после компиляции данного текста mylib.asm. Если программа выводит некоторое слово с помощью hexw, то эта программа, после компиляции, собирается командой
tlink mylib + имя
в результате которой будет создан загрузочный модуль имя.exe.
Напишем подпрограмму вывода числа в десятичном виде. Небольшая модификация позволит превратить ее в подпрограмму для вывода восьмеричного числа. С этой целью воспользуемся арифметической операцией деления:
div bx ; ax = (dx:ax)/bx
записывающей в ax частное от деления регистровой пары (dx:ax), a в регистр dx – остаток. Все числа рассматриваются как беззнаковые. Поскольку наибольшее беззнаковое число равно 65535, будем выводить пять десятичных разрядов числа. Первая цифра будет равна целой части частного от деления этого числа на 10000. Вторая получается делением полученного остатка на 1000. Снова получим остаток, который надо поделить на 100, и т.д. Например, если число x = 1234, то получим цифры ai следующим образом:
a1 = 01234 / 10000 = 0, остаток = 1234;
a2 = 1234 / 1000 = 1, остаток = 234;
a3 = 234 / 100 = 2, остаток = 34;
a4 = 34 / 10 = 3, остаток = 4;
a5 = 4.
Подпрограмма:
bintodec proc ;вывод ax в десятичном виде
mov bx,10000 ;вывод ax/bx
call show ;остаток в ax
mov bx,1000
call show
mov bx,100
call show
mov bx,10
call show
add al,’0′ ;вывод последней
mov dl,al ;цифры
call display
call crlf ;переход на новую строку
ret
bintodec endp
Подпрограмма show делит ax на bx и остаток возвращает в ax:
show proc
mov dx,0
div bx
mov di,dx
add al,’0′
mov dl,al
call display
mov ax,di
ret
show endp
Аналогичным образом составляется подпрограмма вывода числа в восьмеричном виде (используется та же подпрограмма show):
bintooct proc ;вывод ax в восьмеричном виде
mov bx,100000o
call show
mov bx,10000o
call show
mov bx,1000o
call show
mov bx,100o
call show
mov bx,10o
call show
add al,’0′
mov al,dl
call display
call crlf
ret
bintooct endp