这就是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链接中观察到此代码的生成。



