Reputation: 33
XLAT doesn't work in MASM.
What can I use instead to get the same behaviour:
XLAT
: Set AL to memory byte DS:[(E)BX + unsigned AL]
Upvotes: 1
Views: 2210
Reputation: 365707
xlatb
is a valid instruction in 16, 32, and 64bit modes. Maybe you need to use the xlatb
mnemonic for MASM? The Intel manual suggests that xlatb
is the right mnemonic when used with implicit operands, or xlat byte ptr [bx]
for the explicit form (where, like movs
, the operand is basically just documentation or segment overrides, and implies the operand size.) Another idea is to see what syntax your disassembler uses for the instruction.
However, using something else is usually a good idea, since it's only a win for code-size, not speed, on modern CPUs (3 uops on Intel Haswell for example). There are usually better alternatives (especially in 32 or 64bit code), like using movzx
to get a zero-extended value into a register you can use as an index.
In normal code, you could do:
; 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
In 8086 code, you could do something like:
; 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
is the only register that can be used in 16bit addressing modes that has separately-usable low and high halves (bl/bh). You need a REX prefix (64bit mode only) to use sil
/ dil
. If you wanted to keep the table pointer in bx
, like xlatb
does, you'd have to zero-extend using a different register and then mov
to si or di.
If the table is static, you can of course use not tie up a register, and just use [table + (e/r)bx]
.
Upvotes: 6