gpt4 book ai didi

assembly - 是否有其他类似于 MOVZX 但在 8086 上支持的指令?

转载 作者:行者123 更新时间:2023-12-02 09:43:04 26 4
gpt4 key购买 nike

我正在尝试找到一条可以替换 MOVZX 的指令,因为我使用的是 EMU8086(它模拟不支持 MOVZX 的 8086)。

我发现的最接近的指令是CBW,它将值放入寄存器AX中,但它仅适用于带符号的值。我需要一些适用于无符号值的东西。

我有什么选择?是否可以用一条指令来完成?

最佳答案

movzx 指令对宽度较小的值进行零扩展,以适应宽度较大的寄存器。例如,movzx 用于将 16 位值移入 32 位寄存器。 (它与 movsx 形成对比,除了使用符号扩展之外,它执行相同的操作。当值无符号时,您可以使用 movzx,并且 movsx 当值被签名时。)

正如您所指出的,这些指令直到 386 才引入,因此如果您的目标是更早一代的处理器,那么您需要找到替代方案。


正如其他人在评论中指出的那样,基本策略是首先将目标寄存器清零,然后将较小的值移入。这将完成与 movzx 完全相同的事情。将寄存器清零的明显方法是使用 mov reg, 0,但是 it is smaller and faster使用xor reg, reg来做到这一点。因此,代码如下:

movzx  edx, WORD PTR [bx]

可以替换为:

xor    edx, edx
mov dx, WORD PTR [bx]

在现代处理器上,这比 movzx 慢,但实际上在 386 和 486 上会更快,而 movzx 相对较慢。当然,在不存在 movzx 的处理器上,您别无选择。您可以通过提前发出xor指令并将其散布在其他代码中来进一步降低成本。


这种方法的一个显着缺点是您无法对存储在寄存器中的值进行就地零扩展。也就是说,当您有如下代码时,无法使用此技巧:

movzx  edx, dx

相反,您必须使用临时寄存器:

xor  eax, eax
mov ax, dx
mov dx, ax ; optional, if you really needed the result to be in DX


或者,如果您对 8 位值进行零扩展,则可以利用以下事实:16 位寄存器的上半部分和下半部分可以在 x86 上独立访问,只需将上 8 位清零即可。例如:

mov    al, BYTE PTR [bx]
xor ah, ah
; now read from value in AX

请注意,这适用于就地零扩展 - 只需将高 8 位清零即可。但是,此技术不能用于对 16 位值进行零扩展,因为无法仅访问 32 位寄存器的高 16 位。


幸运的是,这些旧架构上对零扩展的需求比现代架构上的要少得多,因为您不必大力防范部分寄存器停顿和错误依赖关系。

<小时/>

在评论中,有人担心 movzx 的所有替代方案都需要多个指令。当然,这是事实。如果有一种方法可以在一条指令中完成此操作,那么 386 就不需要引入 movzx。如果您担心执行速度,请考虑我上面所说的,xor+mov 将与 movzx 一样快,如果它是可用的,甚至更快。

如果您担心指令数量,请放心,更少代码并不一定意味着更快代码。事实上,在很多情况下,添加额外的指令可以使你的程序执行得更快。如果您正在尝试优化特定的代码块,我鼓励您在此处或在 Code Review 上提出有关它的问题。 (我们需要更多的汇编语言问题!)。

关于assembly - 是否有其他类似于 MOVZX 但在 8086 上支持的指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31357528/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com