К группе команд преобразования данных можно отнести множество команд про-
цессора, но большинство из них имеют те или иные особенности, которые требуют
отнести их к другим функциональным группам (см. рис 3.3). Поэтому из всей со-
вокупности команд процессора непосредственно к командам преобразования дан-
ных можно отнести только одну команду
xlat [адрес_таблицы_перекодировки]
Это очень интересная и полезная команда. Ее действие заключается в том, что
она замещает значение в регистре AL другим байтом из таблицы в памяти, располо-
женной по адресу, указанному операндом адрес_таблицы_перекодировки. Слово «таб-
лица» весьма условно; по сути, это просто строка байтов. Адрес байта в строке,
которым будет производиться замещение содержимого регистра AL, определяется
суммой (ВХ) + (AL), то есть содержимое AL играет роль индекса в байтовом массиве.
При работе с командой XLAT обратите внимание на следующий тонкий момент.
Хотя в команде указывается адрес строки байтов, из которой должно быть извле-
чено новое значение, этот адрес должен быть предварительно загружен (напри-
мер, с помощью команды LEA) в регистр ВХ. Таким образом, операнд адрес_табли-
цы_перекодировки на самом деле не нужен (на это указывают квадратные скобки).
Что касается строки байтов (таблицы перекодировки), то она представляет собой
область памяти размером от 1 до 255 байт (диапазон числа без знака в 8-разрядном
регистре).
В качестве иллюстрации работы данной команды мы рассмотрим программу
из листинга 6. 1 (см. главу 6). Вы помните, что эта программа преобразовывала дву-
значное шестнадцатеричное число, вводимое с клавиатуры (то есть в символьном
виде), в эквивалентное двоичное представление в регистре AL. В листинге 7.3 при-
веден вариант этой программы с использованием команды XLAT.
Листинг 7.3. Использование таблицы перекодировки
Prg_7_3.asm _ _
<2> ;Программа преобразования двузначного шестнадцатеричного числа
<3> ;в двоичное представление с использованием команды xlat.
<4> ;Вход: исходное шестнадцатеричное число; вводится с клавиатуры.
<5> ;Выход: результат преобразования в регистре al
<6> masm
<7> model small
<8> .data ;сегмент данных
<9> message db "Введите две шестнадцатеричные цифры, $"
<10> tabl db 48 dup(O) ,6, 1.2,3 .4.5.6.7,8.9. 7 dup (0)
<11> db 0ah,0bh,0ch,0dh,0eh,0fh, 26 dup (0)
<12> db 0ah,0bh,0ch,0dh,0eh,0fh, 152 dup (0)
<13> .stack 256 ;сегмент стека
<14> .code
<15> ;начало сегмента кода
<16> main proc ; начало процедуры main
<17> mov ax,@data :физический адрес сегмента данных в регистр ах
<18> mov ds.ax ;ax записываем в ds
<19> lea bx.tabl ;загрузка адреса строки байт в регистр Ьх
<20> mov ah, 9
<21> mov dx, offset message
<22> int 21h ;вывести приглашение к вводу
<23> хог ах, ах ;очистить регистр ах
<24> mov ah, In ;значение lh в регистр ah
<25> int 21h ; вводим первую цифру в al
<26> xlat ; перекодировка первого введенного символа в al
<27> mov dl.al
<28> shl dl,4;cflBnr dl влево для освобождения места для младшей цифры
<29> int 21h ;ввод второго символа в al
<30> xlat перекодировка второго введенного символа в al
<31> add al.dl складываем для получения результата
<32> mov ах, 4c00h; пересылка 4c00h в регистр ах
<33> int 21h ;завершение программы
<34> endp main ;конец процедуры main
<36> end main ; конец программы с точкой входа main
Сама по себе программа проста; сложность вызывает обычно формирование
таблицы перекодировки. Обсудим этот вопрос подробнее. Прежде всего нужно
определиться со значениями тех байтов, которые вы будете изменять. В нашем
случае это символы шестнадцатеричных цифр. В главе 6 мы рассматривали их
ASCII-коды. Поэтому мы конструируем в сегменте данных таблицу, в которой на
места байтов, соответствующих символам шестнадцатеричных цифр, помещаем
их новые значения, то есть двоичные эквиваленты шестнадцатеричных цифр. Стро-
ки 10-12 листинга 7.3 демонстрируют, как это сделать. Байты этой таблицы, сме-
щения которых не совпадают со значением кодов шестнадцатеричных цифр, нуле-
вые. Таковыми являются первые 48 байт таблицы, промежуточные байты и часть
в конце таблицы. Желательно определить все 256 байт таблицы. Дело в том, что
если мы ошибочно поместим в AL код символа, отличный от символа шестнадцате-
ричной цифры, то после выполнения команды XLAT получим непредсказуемый ре-
зультат. В случае программы из листинга 7.3 это будет ноль, что не совсем коррект-
но, так как непонятно, что же в действительности было в AL: код символа 0 или
что-то другое. Поэтому, наверное, есть смысл здесь поставить «защиту от дурака»,
поместив в неиспользуемые байты таблицы какой-нибудь определенный символ.
После каждого выполнения команды XLAT нужно будет просто контролировать
значение в AL на предмет совпадения с этим символом, и если оно имело место,
выдавать сообщение об ошибке.
После того как таблица составлена, с ней можно работать. В сегменте команд
строка 19 инициализирует регистр ВХ значением адреса таблицы TABL. Далее все
очень просто. Поочередно вводятся символы двух шестнадцатеричных цифр и про-
изводится их перекодировка в соответствующие двоичные эквиваленты. |