您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用局部变量的编译器,无需调整RSP

使用局部变量的编译器,无需调整RSP

这就是x86-64 ABI的所谓“红色区域” 。维基百科摘要

在计算中,红色区域是函数堆栈帧中超出当前堆栈指针的固定大小区域,该区域未被该函数保留。被调用函数可以使用红色区域来存储局部变量, 。中断/异常/信号处理程序不能修改此内存区域。System V使用的x86-64 ABI要求一个128字节的红色区域,该区域直接从堆栈指针的当前值开始。

在64位Linux用户代码中,只要使用的字节数不超过128个即可。这是叶函数(即不调用其他函数函数)最主要使用的优化

如果使用该选项将示例程序编译为带有 GCC (或兼容的编译器)的64位Linux程序,-mno-red-zone则会生成如下所示的代码

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16;     <<============  Observe RSP is Now being adjusted.
        mov     DWORD PTR [rbp-4], 0
.L3:
        cmp     DWORD PTR [rbp-4], 9
        jg      .L2
        mov     DWORD PTR [rbp-8], 0
        add     DWORD PTR [rbp-4], 1
        jmp     .L3
.L2:
        mov     eax, 0
        leave
        ret

可以在此godbolt.org链接上观察到此代码生成

对于32位Linux用户程序,不调整堆栈指针将是一件坏事。如果要将问题中的代码编译为32位代码(使用-m32选项),main则会显示以下代码

main:
        push    ebp
        mov     ebp, esp
        sub     esp, 16;     <<============  Observe ESP is being adjusted.
        mov     DWORD PTR [ebp-4], 0
.L3:
        cmp     DWORD PTR [ebp-4], 9
        jg      .L2
        mov     DWORD PTR [ebp-8], 0
        add     DWORD PTR [ebp-4], 1
        jmp     .L3
.L2:
        mov     eax, 0
        leave
        ret

您可以在此gotbolt.org链接中观察到此代码生成

其他 2022/1/1 18:17:03 有532人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶