有没有一种方法可以从XMM寄存器中推送一个打包的双字整数到栈中?然后在需要时再将其弹出?
理想情况下,我正在寻找类似于通用寄存器的PUSH或POP命令,我已经查看了英特尔手册,但我可能错过了该命令或者确实没有这样的命令...
还是说我必须将值解包到通用寄存器中,然后将它们推送到栈中?
不,x86架构下没有这样的汇编指令,但你可以做类似这样的操作:
//Push xmm0
sub esp, 16
movdqu dqword [esp], xmm0
//Pop xmm0
movdqu xmm0, dqword [esp]
add esp, 16
编辑:
上面的代码示例是直接模拟推入/弹出操作。
如果你在栈上同时使用其他本地变量,那么ebp
寄存器必须首先正确设置,例如:
push ebp
mov ebp, esp
sub esp, LocaStackVariablesSize
//... your code
mov esp, ebp
pop ebp
ret
在这种情况下,您也可以使用 Daniel 的解决方案!我建议为此使用单独的、16位对齐的堆栈,以便您可以使用movdqa而不是movdqu。这两个指令之间的执行时间略有不同!
and esp, -16
;保存/恢复原始ESP可能比单独使用堆栈更便宜。 - Peter Cordesmovdqa
代替 movdqu
,一切都没问题。
但是,如果操作系统不需要堆栈对齐,那么即使使用 and esp, -16
也不会有太大的帮助,因为在弹出最后一个xmm寄存器之后,你还是必须恢复原始的 esp
。 - Zoltán Bíró__m256
时使用and esp,-16
或-32
或它们需要的任何对齐方式,或者如果您使用alignas(16)
。https://godbolt.org/g/6856no。`-mpreferred-stack-boundary = 2告诉gcc仅使用4字节堆栈对齐。(在32位模式下,它选择使用
rep stos`而不是向量存储,但确实提供所请求的对齐方式。)堆栈对齐开销仅在每个函数中发生一次(它可能会占用额外的寄存器,但手动可以溢出)。 - Peter Cordes