首页 > 后端开发 > C++ > C/C 编译器是否使用 Push/Pop 指令来创建局部变量?

C/C 编译器是否使用 Push/Pop 指令来创建局部变量?

Mary-Kate Olsen
发布: 2024-12-09 11:58:10
原创
301 人浏览过

Do C/C   Compilers Utilize Push/Pop Instructions for Local Variable Creation?

具有局部变量的 Push/Pop 指令的 C/C 编译器

简介

传统的 C/C 编译器通过增加堆栈指针来创建局部变量(ESP)一次。然而,使用入栈/出栈指令可以产生更紧凑且可能更快的代码。本文探讨了哪些编译器提供此优化。

编译器支持

研究表明所有四种主要 x86 编译器(GCC、Clang、ICC 和 MSVC)当前都不使用推送/弹出创建局部变量的指令。相反,他们更喜欢旧方法的变体,使用 sub rsp, c 来减少堆栈指针。

Push/Pop 的优点

对局部变量使用 push/pop 有几个优点:

  • 代码大小减少:推送指令与sub/mov 对为 9-11 个字节。
  • 潜在的性能改进:在具有堆栈引擎的 CPU 上,推送操作可能比 sub rsp 产生更少的堆栈同步 uops,从而使其速度更快

何时避免 Push/Pop

虽然 Push/Pop 可以是有益的,但不建议在所有情况下都这样做。例如,与 [rsp x] 寻址模式混合时,它可能会导致额外的堆栈同步 uops。

实际用例

考虑以下函数:

int extfunc(int *,int *);

void foo() {
    int a=1, b=2;
    extfunc(&a, &b);
}
登录后复制

使用改进的编译push/pop:

# compiled for the x86-64 System V calling convention:
# integer args in rdi, rsi  (,rdx, rcx, r8, r9)
    push    2                   # only 2 bytes
    lea     rdi, [rsp + 4]
    mov     dword ptr [rdi], 1
    mov     rsi, rsp                # special case for lea rsi, [rsp + 0]
    call    extfunc(int*, int*)
    pop     rax                   # alternative to add rsp,8
    ret
登录后复制

注意: 此示例通过将 push 指令的最后 4 个字节与 lea 指令的前 4 个字节重叠来优化紧凑性和速度.

结论

虽然push/pop指令可以为创建本地代码提供代码大小和性能优势变量,目前主流 C/C 编译器尚未使用它们。这可能是由于可能存在额外的堆栈同步微指令以及管理堆栈偏移的复杂性。然而,随着硬件和编译器优化的发展,局部变量的推送/弹出将来可能会得到更广泛的采用。

以上是C/C 编译器是否使用 Push/Pop 指令来创建局部变量?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板