XLAT指令在8086中做了什么?

Zah*_*han -3 x86 assembly

我无法找到一个明确的例子来理解

1. XLAT指令有什么作用?
2.我们为什么要使用它?(应用程序).

我的书描述XLAT

XLAT 简化了查找表的实现[1]

但我不明白作者在谈论哪个表格?
任何帮助都会很明显!

[1] 8088和8086微处理器.Walter A. Triebel
Avtar Singh

Bri*_*uch 6

它对DS:BX(实模式)中指定的表执行简单的基于字节的查找.例如,用于执行直接字符集转换(ASCII到EBCDIC).我过去曾用它来做其他基于索引/结果的字节查找.缓慢但紧凑的指令.


Ped*_*d7g 6

如果你知道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
Run Code Online (Sandbox Code Playgroud)

[ds:bx + al]不是合法的内存操作数mov,但xlat接受它,实际上这是xlat解决内存的唯一方法(你不能修改它来使用不同的寄存器).

您在表格中放置了哪种数据,或者您在内存中找到表格的位置取决于您.也是你用它的原因.这与内存分页或其他一些内存OS表无关,这只是纯粹的用户数据.

例如,如果您的食物指数为0..255,价格也适合8位,您可以使用它将菜单中的食物指数转换为食物价格.然后为包含价格数据的表保留256个字节,并加载ds:bx该表的地址,将食物的索引放入al,并将xlat索引转换为表中的价格.


在我的希腊国旗绘图DOS 51B COM(二进制)()我使用xlat指令将strip-column 0..4的索引转换为蓝/蓝/白/蓝/蓝配置.

我首先检查[x,y]坐标是否位于旗帜的左上角,其中是蓝色矩形上的大白十字.如果在外面,像素的颜色是简单的(y div strip_size) & 1交替蓝/白色.

但是在交叉区域内,我计算5x5网格,中间行条带是全白色.必须[blue, blue, white, blue, blue]根据x坐标(它所属的柱带)绘制中间上方和下方的两个条带.要将这种从[0, 1, 2, 3, 4]值转换为[1, 1, 0, 1, 1]I使用xlat指令,指向代码本身,并屏蔽指令操作码以仅提取最低位(奇数/偶数).通过对代码中的指令进行小的重新排列,我设法在地址处获得所需的奇数/偶数指令操作码字节,以便我可以通过它们xlat.

如果我通过if-else分支或其他算法进行转换,则需要更多字节的代码,而不是简单地xlat重用已经需要的值bxal.


在常见的应用程序中,您几乎找不到任何xlat指令用法.它是8086次的古体,编译器肯定不会使用它,而且大部分都是手工编写的汇编,因为通常你可以使用简单mov al,[bx+si]或类似的东西.

在32b模式下,如果您知道该值已经零扩展到32b,mov al,[ebx+eax]则速度快于xlat(具有相同的结果).

在代码打高尔夫球时,当您尝试生成最短的机器代码时,xlat可能会很方便(到目前为止,我需要它生命中的两倍,十六进制数字格式,以及希腊国旗绘图代码).

  • 重要提示:`ds:[bx + al]`“寻址模式”使用零扩展`AL`。所以C版本肯定需要使用`unsigned byte al`。这显然是你想要的,但不是你从 C 中的有符号数组索引中得到的。 (3认同)
  • 顺便说一句,如果已知 EAX 的其余部分为零,则在 32 位代码中“movzx eax, byte [ebx+eax]”会更有效(对于速度)(或“add cl, [ebx+eax]”或无论如何),但是 `xlatb` 确实可以用于代码大小优化。它可能在没有“movzx”(386)的 8086 上最有用,因为“movzx”将字节索引零扩展到完整寄存器可以解决相同的问题。 (2认同)
  • 这里没有涵盖的事实是 [`xlatb`](https://ulukai.org/ecm/doc/insref.htm#insXLATB) 可以覆盖其段。因此它默认为“ds:(r/e)bx + al”,但可以采用任何段。 (2认同)