我使用VC ++ 2010编译器编译了下面的代码:
__declspec(dllexport)
unsigned int __cdecl __mm_getcsr(void) { return _mm_getcsr(); }
生成的代码是:
push ECX
stmxcsr [ESP]
mov EAX, [ESP]
pop ECX
retn
为什么有push ECX
/ pop ECX
指令对?
答案 0 :(得分:12)
编译器在堆栈上腾出空间来存储MXCSR。它可以同样做得很好:
sub esp,4
stmxcsr [ESP]
mov EAX, [ESP]
add esp,4
retn
但是“推动ecx”可能更短或更快。
答案 1 :(得分:3)
此处的推送用于分配4个字节的临时空间。 [ESP]
通常会指向推送的返回地址,我们无法覆盖它。
ECX
将在此处被覆盖,但是,ECX
可能是您要定位的ABI中的易失性寄存器,因此函数不必保留ECX
。
这里使用推/弹的原因是空间(可能是速度)优化。
答案 2 :(得分:0)
它创建了一个堆栈顶部条目,ESP现在称之为stmxcsr指令的目标。然后将结果存储在EAX中以进行返回。