如何解决将 8 位值移动到 BX 寄存器(16 位)的问题?
mov al, 10h
mov bx, al
为此,我得到:
operands do not match: 16 bit and 8 bit register
如何解决将 8 位值移动到 BX 寄存器(16 位)的问题?
mov al, 10h
mov bx, al
为此,我得到:
operands do not match: 16 bit and 8 bit register
答案取决于您是要对值进行零扩展还是符号扩展,以及您是否可以使用从 80386 开始的可用指令。为了获得更好的性能,如果可用movzx
,则应使用 80386 或更高版本的代码。movsx
将上半部分归零,然后移至下半部分。
xor bh, bh
mov bl, al
(或者等效地,在一些后来的 CPU 上更有效,xor bx, bx
在替换低 8 之前将整个 16 位归零。)
如果没有movsx
,您可能想使用cbw
仅适用于AL
->AX
的。最简单的方法是AH
在复制到之前覆盖BX
,因为您的值已经在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 上保存指令可能涉及规划您在哪个寄存器中保留的内容,以便它已经在正确的位置用于类似cbw
或mul
使用隐式寄存器的指令。到 386 年,英特尔添加了其中一些适用于任何寄存器的版本。
使用movzx
.
movzx bx, al
为了获得最佳性能,零一直扩展到 32 位。
movzx ebx, al
Use movsx
,类似于cbw
但适用于任何dst、src,甚至包括内存源。
movsx bx, al
如果可能,将符号一直扩展到 32 位以获得更好的性能。
movsx ebx, al
其他方法neg
:也可以使用/设置上半部分sbb
,符号或零扩展的算术移位或逻辑移位也是可能的。(特别是如果您的值始于 AH 之类的寄存器)。请参阅MASM 程序集将 8 位寄存器移动到 16 位寄存器(即 mov cx, ch)