8086 XLAT 替代品

8086 XLAT alternative

XLATMASM 中不起作用。

我可以使用什么来获得相同的行为:

XLAT : Set AL to memory byte DS:[(E)BX + unsigned AL]

xlatb is a valid instruction in 16, 32, and 64bit modes。也许您需要为 MASM 使用 xlatb 助记符?英特尔手册建议 xlatb 与隐式操作数一起使用时是正确的助记符,或者 xlat byte ptr [bx] 用于显式形式(其中,如 movs,操作数基本上只是文档或段覆盖,并暗示操作数的大小。)另一个想法是查看反汇编程序对指令使用的语法。


但是,使用其他东西通常是个好主意,因为在现代 CPU 上,这只是代码大小而非速度的胜利(例如 3 uops on Intel Haswell)。通常有更好的选择(尤其是在 32 位或 64 位代码中),例如使用 movzx 将零扩展值放入可用作索引的寄存器中。

在普通代码中,你可以这样做:

; table in rbx
movzx  eax,  src                 ; or any other way of producing a zero-extended result in rax
movzx  eax, byte ptr [rbx + rax]     ; a movzx load avoids false deps and partial-reg slowdowns

在 8086 代码中,你可以这样做:

; pointer to the table in DI or SI
xor  bx,bx             ; can be hoisted out of a loop, if bh will stay zeroed

mov  bl, src   ; src can be any addressing mode, or the result of a computation

mov  bl, [si + bx]     ; this is the same load that xlat does, your choice of dest

bx 是唯一可用于 16 位寻址模式且具有可单独使用的低半部分和高半部分 (bl/bh) 的寄存器。您需要一个 REX 前缀(仅限 64 位模式)才能使用 sil / dil。如果你想将 table 指针保留在 bx 中,就像 xlatb 那样,你必须使用不同的寄存器进行零扩展,然后 mov 到 si 或 di .

如果table是静态的,当然可以不占用寄存器,直接用[table + (e/r)bx].