假设我们有下面的代码,其中 val1、val2 和 sum 是 32 位,BX 是 BX 寄存器。
sum = (val1 + BX) - val2
Run Code Online (Sandbox Code Playgroud)
在编写代码并使用BX寄存器时,我们可以EBX直接使用而不是使用吗movzx EBX, BX?
简短的回答是否定的。
\nBX是 16 位值并且EBX是 32 值。\xc2\xa0 虽然它们可以表示相同的数字,但没有要求它们这样做。\xc2\xa0 存储到 BX 中不会修改完整的EBX,因此如果您不这样做知道BX它的值是如何得到的,你不能假设EBX拥有相同的数字 \xe2\x80\x94 我们只知道只有低 16 位是相同的。
请注意,混合数据大小时,您需要充分注意符号!\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
如果您不知道 的符号BX,那么问题就不明确。
我们通常找出值的有符号性的方法是由程序员通过使用 C 或其他语言的数据类型的变量声明来告诉 \xe2\x80\x94。\xc2\xa0 的类型当需要扩展 16 位值以参与 32 位算术时,变量会被编译器记住并翻译成适当的指令,例如 和movsx。 \xc2\xa0 因此,程序员编写了一个程序,它通知编译器要做什么movzxdo.\xc2\xa0 如果您显示的代码片段缺少编译器(或汇编程序员)完整且可编译的信息(例如类型声明)。
(您还必须考虑是否允许修改EBX,我认为通常在代码片段的上下文中,答案是肯定的,因为这里BX已经有一个感兴趣的值。\xc2\xa0 但是,要清楚您可以将扩展值发送到另一个寄存器,例如movzx EAX, BX\xe2\x80\x94 不必将符号/零扩展到同一寄存器中。)