Sla*_*Bot 0 assembly sign-extension x86-16 emu8086 zero-extension
如何解决将8位值移至BX寄存器(16位)的问题?
mov al, 10h
mov bx, al
Run Code Online (Sandbox Code Playgroud)
为此,我得到:
operands do not match: 16 bit and 8 bit register
Run Code Online (Sandbox Code Playgroud)
答案取决于是否要将该值零扩展或符号扩展,以及是否可以使用从80386开始的可用指令。为了获得更好的性能,如果movzx和movsx可用,则应使用80386或更高版本的代码。
将上半部分调零,然后移到下半部分。
xor bh, bh
mov bl, al
Run Code Online (Sandbox Code Playgroud)
(或者等效地,在以后的一些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
Run Code Online (Sandbox Code Playgroud)
如果要保留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
Run Code Online (Sandbox Code Playgroud)
将指令保存在8086上可能涉及计划保存在哪个寄存器中的内容,因此对于诸如cbw或mul使用隐式寄存器的指令,它已经在正确的位置。到386年,英特尔增加了其中一些可与任何寄存器一起使用的版本。
使用movzx。
movzx bx, al
Run Code Online (Sandbox Code Playgroud)
为了获得最佳性能,零会一直扩展到32位。
movzx ebx, al
Run Code Online (Sandbox Code Playgroud)
Use movsx,就像,cbw但是适用于任何dst src,甚至包括内存源。
movsx bx, al
Run Code Online (Sandbox Code Playgroud)
如果可能的话,将符号一直扩展到32位,以获得更好的性能。
movsx ebx, al
Run Code Online (Sandbox Code Playgroud)
其他方法:也可以用neg/ 设置上半部分,sbb符号或零扩展的算术移位或逻辑移位也可以。(特别是如果您的值始于AH之类的寄存器中)。请参见MASM组件将8位寄存器移动到16位寄存器(即mov cx,ch)