我找不到一个明确的例子来理解
XLAT
[1] The 8088 and 8086 Microprocessors. Walter A. Triebel Avtar Singh
9o685dep1#
如果你知道C,那么它的工作方式如下:
const uint8_t table[256] = { ...some byte constants (table data) ... }; const uint8_t* ds_bx = table; uint8_t al = <some value to translate>; al = ds_bx[al]; // al = table[al]; // like "mov al,[ds:bx + al]" in ASM
[ds:bx + al]不是mov指令的法律的内存操作数,但xlat接受它,实际上这是xlat寻址内存的唯一方式(您不能修改它以使用不同的寄存器)。你在表中放入什么样的数据,或者你在内存中把表放在什么位置,这取决于你。还有你用它做什么。这与内存分页或其他内存操作系统表无关,这只是纯粹的用户数据。例如,你可以用它把菜单中的食物索引转换成食物的价格,如果你的食物索引是0..255,价格也可以容纳在8位中。然后你为包含价格数据的表保留256个字节,并加载ds:bx与该表的地址,把食物索引放入al,xlat将把该索引从表中转换成价格。在我的Greece-flag绘图DOS 51 B COM(binary)(source)中,我使用xlat指令将带列0..4的索引转换为蓝/蓝/白色/蓝/蓝配置。我首先检查[x,y]坐标是否在flag的左上角,这里是蓝色矩形上的白色大叉。如果在左上角,像素的颜色是简单的(y div strip_size) & 1蓝/白交替。但在交叉区域内,我计算的是5x 5网格,中间一行的条带是全白色的,中间上下两个条带必须根据x坐标绘制成[blue, blue, white, blue, blue]为了将[0, 1, 2, 3, 4]值转换为[1, 1, 0, 1, 1],我使用了xlat指令,指向代码本身,通过对代码中的指令进行小的重新排列,我设法在我可以通过xlat到达它们的地址处获得想要的奇/偶指令操作码字节。如果我通过if-else分支或其他算法进行转换,与简单的xlat在bx和al中重用已经需要的值相比,它将占用更多的代码字节。在一般的应用程序中,你几乎找不到xlat指令的任何用法。它是8086次的古语,编译器肯定不会使用它,大多数手工编写的汇编程序也不会使用它,因为通常你可以使用简单的mov al,[bx+si]或类似的东西。在32 b模式下,如果您知道该值已经零扩展为32 b,则mov al,[ebx+eax]比xlat更快(结果相同)。在代码高尔夫中,当你试图生成最短的机器代码时,xlat可能很方便(到目前为止,我一生中需要它两次,一次是十六进制数字格式化,另一次是希腊国旗绘制代码)。
[ds:bx + al]
mov
xlat
ds:bx
al
(y div strip_size) & 1
[blue, blue, white, blue, blue]
[0, 1, 2, 3, 4]
[1, 1, 0, 1, 1]
if-else
bx
mov al,[bx+si]
mov al,[ebx+eax]
juud5qan2#
它对DS:BX中指定的表进行简单的基于字节的查找(在真实的模式下)。例如,用于直接字符集转换(ASCII到EBCDIC)。我过去曾用它进行过其他基于索引/结果的字节查找。速度慢,但指令紧凑。
rsaldnfx3#
很久没有用8086编程了。我记得它是用于查找表的。如果你懂C语言,你可以把它和switch()语句比较一下,当使用一个好的编译器时,它会把所有的情况都转换成一个查找(跳转)表,而不是使用带有大量if-then-else的“意大利面条编程”。然后,每种情况都转换为跳转表中的地址+偏移量,跳转表中包含要调用的函数的地址。然后执行一个简单的JMP就完成了。没有使用比较语句。只有加法,这样无论你有多少个案例都能快速完成。
ycl3bljg4#
XLAT使用AL寄存器的内容作为表索引,在内存的表中查找字节项,然后将表项的内容复制回AL寄存器。
ldioqlga5#
TAB DB '0123456789ABCDEF' MOV AL,1101B ; Index = 13 MOV BX,OFFSET TAB XLAT
A1的索引为13,因此此代码后的A1将为= 'D'
5条答案
按热度按时间9o685dep1#
如果你知道C,那么它的工作方式如下:
[ds:bx + al]
不是mov
指令的法律的内存操作数,但xlat
接受它,实际上这是xlat
寻址内存的唯一方式(您不能修改它以使用不同的寄存器)。你在表中放入什么样的数据,或者你在内存中把表放在什么位置,这取决于你。还有你用它做什么。这与内存分页或其他内存操作系统表无关,这只是纯粹的用户数据。
例如,你可以用它把菜单中的食物索引转换成食物的价格,如果你的食物索引是0..255,价格也可以容纳在8位中。然后你为包含价格数据的表保留256个字节,并加载
ds:bx
与该表的地址,把食物索引放入al
,xlat
将把该索引从表中转换成价格。在我的Greece-flag绘图DOS 51 B COM(binary)(source)中,我使用
xlat
指令将带列0..4的索引转换为蓝/蓝/白色/蓝/蓝配置。我首先检查[x,y]坐标是否在flag的左上角,这里是蓝色矩形上的白色大叉。如果在左上角,像素的颜色是简单的
(y div strip_size) & 1
蓝/白交替。但在交叉区域内,我计算的是5x 5网格,中间一行的条带是全白色的,中间上下两个条带必须根据x坐标绘制成
[blue, blue, white, blue, blue]
为了将[0, 1, 2, 3, 4]
值转换为[1, 1, 0, 1, 1]
,我使用了xlat
指令,指向代码本身,通过对代码中的指令进行小的重新排列,我设法在我可以通过xlat
到达它们的地址处获得想要的奇/偶指令操作码字节。如果我通过
if-else
分支或其他算法进行转换,与简单的xlat
在bx
和al
中重用已经需要的值相比,它将占用更多的代码字节。在一般的应用程序中,你几乎找不到
xlat
指令的任何用法。它是8086次的古语,编译器肯定不会使用它,大多数手工编写的汇编程序也不会使用它,因为通常你可以使用简单的mov al,[bx+si]
或类似的东西。在32 b模式下,如果您知道该值已经零扩展为32 b,则
mov al,[ebx+eax]
比xlat
更快(结果相同)。在代码高尔夫中,当你试图生成最短的机器代码时,
xlat
可能很方便(到目前为止,我一生中需要它两次,一次是十六进制数字格式化,另一次是希腊国旗绘制代码)。juud5qan2#
它对DS:BX中指定的表进行简单的基于字节的查找(在真实的模式下)。例如,用于直接字符集转换(ASCII到EBCDIC)。我过去曾用它进行过其他基于索引/结果的字节查找。速度慢,但指令紧凑。
rsaldnfx3#
很久没有用8086编程了。我记得它是用于查找表的。如果你懂C语言,你可以把它和switch()语句比较一下,当使用一个好的编译器时,它会把所有的情况都转换成一个查找(跳转)表,而不是使用带有大量if-then-else的“意大利面条编程”。
然后,每种情况都转换为跳转表中的地址+偏移量,跳转表中包含要调用的函数的地址。
然后执行一个简单的JMP就完成了。没有使用比较语句。只有加法,这样无论你有多少个案例都能快速完成。
ycl3bljg4#
XLAT
使用AL寄存器的内容作为表索引,在内存的表中查找字节项,然后将表项的内容复制回AL寄存器。ldioqlga5#
A1的索引为13,因此此代码后的A1将为= 'D'