如何将较小的值弹出到寄存器中
How to pop a lesser-sized value into a register
我有一个 2 字节的值存储在堆栈中,我想 pop
将它存入寄存器。我可以通过使用其中的 16 位寄存器在其中一个通用寄存器上执行此操作,例如:
popw %cx
有没有办法将它放入另一个寄存器,例如r11
并用零填充它?类似于:
popzwq %r11 # making up the syntax
或者这样做的正确方法是什么?
通常你首先通过从不使用pushw来避免这种情况,而是在压入/弹出时总是使用full-width(64位)堆栈槽。那也保持堆栈对齐。此外,通常你只会在进入/离开函数时使用 push/pop 到 save/restore 寄存器。 (没有低位部分是 call-preserved 而不是高位字节的调用约定,通常 save/restore 完整寄存器最有效。)
但如果您确实需要它,只需用 2 条指令模拟它即可。
movzwl (%rsp), %ecx # or %r11d. implicitly zero-extends into the full 64-bit reg
add , %rsp # or if you need to preserve FLAGS,
# lea 2(%rsp), %rsp
没有 zero-extending 种流行形式; 8086 只能弹出 full-width(16 位)寄存器,因此没有要修改的现有操作码。 386 并没有引入任何 zero-extending 相当于 movzx 或 movsx 的 pop;几乎没有人会从中受益:普通代码在使用 full-width push/pop 时使用它。 (更常见于当时常见的遗留 stack-args 调用约定,而不是前几个参数的现代高效注册参数。)
所以不值得在晶体管和操作码编码上花费 space。
或者如果您不想 zero-extend,pop %r11w
。 (不确定您是否不知道 r8..r15 的 low-8 / low-16 / low-32 寄存器的名称,或者为什么您没有在第二个示例中使用 RCX 来与 pop cx 进行对比)。
我有一个 2 字节的值存储在堆栈中,我想 pop
将它存入寄存器。我可以通过使用其中的 16 位寄存器在其中一个通用寄存器上执行此操作,例如:
popw %cx
有没有办法将它放入另一个寄存器,例如r11
并用零填充它?类似于:
popzwq %r11 # making up the syntax
或者这样做的正确方法是什么?
通常你首先通过从不使用pushw来避免这种情况,而是在压入/弹出时总是使用full-width(64位)堆栈槽。那也保持堆栈对齐。此外,通常你只会在进入/离开函数时使用 push/pop 到 save/restore 寄存器。 (没有低位部分是 call-preserved 而不是高位字节的调用约定,通常 save/restore 完整寄存器最有效。)
但如果您确实需要它,只需用 2 条指令模拟它即可。
movzwl (%rsp), %ecx # or %r11d. implicitly zero-extends into the full 64-bit reg
add , %rsp # or if you need to preserve FLAGS,
# lea 2(%rsp), %rsp
没有 zero-extending 种流行形式; 8086 只能弹出 full-width(16 位)寄存器,因此没有要修改的现有操作码。 386 并没有引入任何 zero-extending 相当于 movzx 或 movsx 的 pop;几乎没有人会从中受益:普通代码在使用 full-width push/pop 时使用它。 (更常见于当时常见的遗留 stack-args 调用约定,而不是前几个参数的现代高效注册参数。) 所以不值得在晶体管和操作码编码上花费 space。
或者如果您不想 zero-extend,pop %r11w
。 (不确定您是否不知道 r8..r15 的 low-8 / low-16 / low-32 寄存器的名称,或者为什么您没有在第二个示例中使用 RCX 来与 pop cx 进行对比)。