BX 与 x86 中的 EBX 具有相同的值吗?

Gam*_*onz 0 x86 assembly

假设我们有下面的代码,其中 val1、val2 和 sum 是 32 位,BX 是 BX 寄存器。

sum = (val1 + BX) - val2
Run Code Online (Sandbox Code Playgroud)

在编写代码并使用BX寄存器时,我们可以EBX直接使用而不是使用吗movzx EBX, BX

Eri*_*idt 5

简短的回答是否定的。

\n

BX是 16 位值并且EBX是 32 值。\xc2\xa0 虽然它们可以表示相同的数字,但没有要求它们这样做。\xc2\xa0 存储到 BX 中不会修改完整的EBX,因此如果您不这样做知道BX它的值是如何得到的,你不能假设EBX拥有相同的数字 \xe2\x80\x94 我们只知道只有低 16 位是相同的。

\n

请注意,混合数据大小时,您需要充分注意符号!\xc2\xa0 例如,我们以 16 位数字 0xffff 为例。\xc2\xa0 如果要将此数字理解为有符号,则 32位等效值为 0xffff ffff (例如 -1 10)。\xc2\xa0 而如果此数字 0xffff 被理解为无符号,则 32 位等效值为 0x0000 ffff (例如 65535 10)。

\n

指令movzx零扩展,以便假定原始BX值是无符号的。\xc2\xa0movsx如果我们假设原始值有符号,则将使用该指令。\xc2\xa0 在这些指令之一之后,和BX中的数值将是如果您知道并应用正确的符号,则相同的数字。BXEBX

\n

如果您不知道 的符号BX,那么问题就不明确。

\n

我们通常找出值的有符号性的方法是由程序员通过使用 C 或其他语言的数据类型的变量声明来告诉 \xe2\x80\x94。\xc2\xa0 的类型当需要扩展 16 位值以参与 32 位算术时,变量会被编译器记住并翻译成适当的指令,例如 和movsx。 \xc2\xa0 因此,程序员编写了一个程序,它通知编译器要做什么movzxdo.\xc2\xa0 如果您显示的代码片段缺少编译器(或汇编程序员)完整且可编译的信息(例如类型声明)。

\n

(您还必须考虑是否允许修改EBX,我认为通常在代码片段的上下文中,答案是肯定的,因为这里BX已经有一个感兴趣的值。\xc2\xa0 但是,要清楚您可以将扩展值发送到另一个寄存器,例如movzx EAX, BX\xe2\x80\x94 不必将符号/零扩展到同一寄存器中。)

\n

  • 有趣的事实:对于零扩展 8 位到 32 位,将 movzx 转移到不同的寄存器在 Intel CPU 上效率更高:它可以受益于 [mov-elimination for Zero Latency and no back-end uop](https:// stackoverflow.com/questions/44169342/can-x86s-mov-really-be-free-why-cant-i-reproduct-this-at-all)。因此,如果可能的话,*更喜欢*`movzx eax, bl`。对于“movsx ebx, bl”与“movsx eax, bl”(符号扩展时数据相关的高位需要一个执行单元)或当前 CPU 上的 16 位寄存器源来说并不重要。首先更喜欢使用 32 位值,例如 movzx/sx 加载。 (3认同)