MOV 8 位到 16 位寄存器(al 到 bx)

MOV 8 bit to 16 bit register (al to bx)

如何解决将 8 位值移动到 BX 寄存器(16 位)的问题?

mov al, 10h
mov bx, al

为此我得到:

operands do not match: 16 bit and 8 bit register 

答案取决于您是要对值进行零扩展还是符号扩展,以及您是否可以使用以 80386 开头的可用指令。为了获得更好的性能,如果 movzxmovsx 可用。

8086 或 80286 上的零扩展

将上半部分归零,然后移动到下半部分。

xor bh, bh
mov bl, al

(或者等效地,在某些后来的 CPU 上效率更高,xor bx, bx 在替换低 8 位之前将整个 16 位归零。)

在 8086 或 80286 上签名扩展

如果没有 movsx,您可能想使用 cbw,它只适用于 AL -> AX。最简单的方法是在复制到 BX 之前覆盖 AH,因为您的值已经在 AL.

 cbw               ; AH = 0 or 0xFF according to top bit of AL
 mov  bx, ax

如果你想保留AH,你可以先复制旧的AX然后在cbw之后交换:

 mov  bx, ax      ; save the old AH (and AL)
 cbw              ; sign-extend AL into AX
 xchg bx, ax      ; BX = sign-extended result, restore original AX

在 8086 上保存指令可能涉及规划您在哪个寄存器中保存的内容,以便它已经位于使用隐式寄存器的 cbwmul 等指令的正确位置。到 386,英特尔添加了其中一些可与任何寄存器一起使用的版本。


80386 或更高版本的零扩展

使用movzx.

movzx bx, al

为获得最佳性能,零扩展一直到 32 位。

movzx ebx, al

在 80386 或更高版本上签名扩展

使用 movsx,它类似于 cbw,但适用于任何 dst、src,甚至包括内存源。

movsx bx, al

如果可能,将符号一直扩展到 32 位以获得更好的性能。

movsx ebx, al

其他方法:设置上半部分neg/sbb也是可以的,符号或零的算术移位或逻辑移位也是可以的延期。 (特别是如果你的价值开始于像 AH 这样的寄存器)。参见