为什么编译器会生成入栈/出栈指令对?

发布于 2024-12-26 19:12:47 字数 303 浏览 3 评论 0原文

我用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指令对?

I compiled the code below with the VC++ 2010 compiler:

__declspec(dllexport)
unsigned int __cdecl __mm_getcsr(void) { return _mm_getcsr(); }

and the generated code was:

push ECX
    stmxcsr [ESP]
    mov EAX, [ESP]
pop ECX
retn

Why is there a push ECX/pop ECX instruction pair?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

编译器正在堆栈上腾出空间来存储 MXCSR。它本来可以同样很好地做到这一点:

sub esp,4
stmxcsr [ESP]
mov EAX, [ESP]
add esp,4
retn

但是“push ecx”可能更短或更快。

The compiler is making room on the stack to store the MXCSR. It could have equally well done this:

sub esp,4
stmxcsr [ESP]
mov EAX, [ESP]
add esp,4
retn

But "push ecx" is probably shorter or faster.

墨落画卷 2025-01-02 19:12:47

这里的push用来分配4个字节的临时空间。 [ESP] 通常会指向推送的返回地址,我们无法覆盖它。

ECX 将在此处被覆盖,但是,ECX 可能是您所针对的 ABI 中的易失性寄存器,因此函数不必保留 ECX< /代码>。

这里使用推送/弹出的原因是空间(也可能是速度)优化。

The push here is used to allocate 4 bytes of temporary space. [ESP] would normally point to the pushed return address, which we cannot overwrite.

ECX will be overwritten here, however, ECX is a probably a volatile register in the ABI you're targeting, so functions don't have to preserve ECX.

The reason a push/pop is used here is a space (and possibly speed) optimization.

缘字诀 2025-01-02 19:12:47

它创建一个栈顶条目,ESP 现在将其称为 stmxcsr 指令的目标。然后将结果存入EAX中供返回。

It creates an top-of-stack entry that ESP now refers to as the target for the stmxcsr instruction. Then the result is stored in EAX for the return.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文