5

我决定学习一门汇编编程语言。我正在使用这个 8086 教程。在底部的练习是找出一些指令中的错误,其中之一是

mov cx, ch 

我在这个主题上发现了一些类似的问题,解释了如何实现它,但现在我想知道为什么禁止这个操作?

假设我在 CH 中有 10d = 00001010b 并希望将其放入 CL 并同时擦除 CH。mov cx, ch似乎这样做是因为它将 10d 显示为 16bit 00000000 00001010 并将其分别放入 CH 和 CL(整个 CX)

它有什么问题,为什么给定的教程要求在这个表达式中查找错误?

4

4 回答 4

8

mov指令用于在相同大小的操作数之间移动。您想要的是8-bit扩展ch到 16-bit cx。有两条指令可用于此目的:

movzx cx,ch  ; zero-extends ch into cx. the upper byte of cx will be filled with zeroes
movsx cx,ch  ; sign-extends ch into cx. the upper byte of cx will be filled with the most significant bit of ch

在这种特殊情况下完成同样事情的另一种方法是:

shr cx,8  ; zero-extend
sar cx,8  ; sign-extend
于 2015-04-18T11:44:37.627 回答
2

问题是,您试图将 8 位寄存器的内容移动ch到 16 位寄存器cx中。你不能这样做,因为寄存器的大小不同。

所以我猜你会收到一条错误消息,比如"invalid combination of opcode and operands"

ps:上面交换了8和16;声明保持不变。例如检查这个概述。如您所见,没有定义不同寄存器大小的组合。这意味着不存在任何代表mov cx, ch.

于 2015-04-18T11:43:53.347 回答
2

您想将 to 的内容移动CHCX8086 上。

在更新的处理器上,例如 80286,您可以将CXright 的值移动 8 个位置,有或没有符号复制:

; zero extend ch into cx
    shr cx,8

; sign extend ch into cx
    sar cx,8

这些指令在 8088 或 8086 上不可用。您必须使用CL来指定移位计数:

; zero extend ch into cx
    mov cl,8
    shr cx,cl

; sign extend ch into cx
    mov cl,8
    sar cx,cl

然而,这种方法非常慢,因为可变数量的位置移位每个位置需要多个周期。

这是一个更快的方法:

; zero extend ch into cx
    mov cl,ch
    xor ch,ch

; sign extend ch into cx
    mov cl,ch
    neg ch     ; set the carry flag if ch is negative
    sbb ch,ch  ; set all bits if ch was negative, clear them otherwise

如果您可以销毁 AX,则可以使用cbw为此设计的代码来节省代码大小。在原始 8086 尤其是 8088 上,小 = 快,因为代码获取是一个主要瓶颈。但是,在现代 x86 上并非如此。

; sign extend ch into ax
    mov   al, ch
    cbw                 ; sign-extend AL into AX
; optionally move back to cx
    xchg  cx, ax        ; smaller than mov cx, ax

为避免破坏 AX,您可以这样做mov cl,chxchg ax,cx; cbw并停在那里,或者做一个决赛xchg ax,cx,只是将 CH 符号扩展到 CX 并恢复其他所有内容。 xchgwith AX 是一个 1 字节指令,and 也是cbwcwd将 AX 扩展到 DX:AX,例如在 16-bit 之前idiv

cbw与 386 完全相同movsx ax, al

于 2019-10-24T14:23:00.313 回答
0

只需按照简单的说明即可

mov cl,ch  ; copy high bits to low
xor ch,ch  ; clear high-bits

它在 16 位编程中很常见,只需要2 个时钟周期

movezx/movsx 的使用需要3 个时钟周期。采用

movsx cx,ch

用于使用符号扩展将字节移动到字

movzx cx,ch

以零扩展名将字节移动到字

于 2017-03-12T08:56:55.400 回答