
x86(16bit)のオペコードマップもかなり塗りつぶし出来てきて、今回は落穂拾い回。XLATとな。何の略かと問えばTRANSLATEみたい。AIの言語変換ではありませんよ。バイト単位で最大256バイトの単なる表引きデス。当時、どなたかがこういう命令が欲しいなどとリクエストしたのかな?お惚け老人には知るよしもなし。
※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら
※実機動作確認(といってもエミュレータなんだけれども)には以下を使用させていただいております。
XLAT
XLAT命令は特に明示的なオペランド引数をとりません。暗黙でBXレジスタにテーブル引きする表の先頭アドレスをセットし、ALレジスタに変換元のバイトを置きます。そしてXLAT命令を実行すると BX + AL 番地から1バイト拾ってきて ALへ代入してくれると。1バイトのコードを1バイトに変換できてめでたしめでたし、という感じです。どういう使い途を想定していたのか、インテルのマニュアルから1か所引用させていただきましょう。
XLAT is useful for translating characters from one code to anather, the classic example being ASCII to EBCDIC or the reverse.
今でもメインフレームをお使いになっていたら EBCDIC コードが使われているのかも知れませんが、普通のパソコンなどではまずお目にかかりません。それにEBCDIC自体にもいろいろあるみたい、バイト対バイトしか変換できないXLAT命令を今だに重宝しているとも思われませぬ。
今となっては何に使うんだろ、という感じもしないでもないデス。
今回実験のプログラム
強力なx86用アセンブラNASM用のソースです。ALに入れた0~9の値をトビトビの(実際は素数列ですが)バイト値に変換するだけのプログラムです。
segment code
..start:
mov ax, data0
mov ds, ax
mov es, ax
mov ax, stack
mov ss, ax
mov sp, stacktop
test:
mov bx, ttab
mov al, 0
xlat
mov al, 9
xlat
fin:
mov ax, 0x4c00
int 0x21
resb 2048
segment data0 align=16
resb 1024 * 63
ttab:
db 2
db 3
db 5
db 7
db 11
db 13
db 17
db 19
db 23
db 29
segment stack class=STACK align=16
resb 2048
stacktop:
dw 1024 dup (0)
stackend:
アセンブルして実行
MS-DOS互換で機能強化されてるフリーなFreeDOS上、以下のステップで上記のアセンブラソース xlat.asm から実行可能なオブジェクトファイルを生成して実行することができます(nasmとwatcom Cがインストール済であること。)
nasm -f obj -l xlat.lst xlat.asm wlink name xlat.exe format dos file xlat.obj debug xlat.exe
デバッガ起動後、今回のプログラムの逆アセンブルを行ったところ。
上の赤枠のバイトと緑枠のバイトを以下でXLAT命令を使って表引きします。
上の黄色枠で、テーブルの先頭アドレスをBXにセットしてます。赤枠のところでALに変換元のコードをセットし、XLATし、その結果がALに入ってます。また緑枠でも同様な操作をしています。デバッガが XLATB と B付で逆アセンブルしてくれているのは、多分、このデバッガが実は32ビットのコードも逆アセンブル可能なデバッガであるためです。32ビットの世界いったときのこの命令の扱いもゾンザイな感じがするのですが、それはまた後で。