c - 当只需要 8 个字节时将堆栈减 24?
问题描述
我有C代码:
long fib(long n) {
if (n < 2) return 1;
return fib(n-1) + fib(n-2);
}
int main(int argc, char** argv) {
return 0;
}
我通过运行gcc -O0 -fno-optimize-sibling-calls -S file.c
产生的尚未优化的汇编代码编译:
.file "long.c"
.text
.globl fib
.type fib, @function
fib:
.LFB5:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
pushq %rbx
subq $24, %rsp
.cfi_offset 3, -24
movq %rdi, -24(%rbp)
cmpq $1, -24(%rbp)
jg .L2
movl $1, %eax
jmp .L3
.L2:
movq -24(%rbp), %rax
subq $1, %rax
movq %rax, %rdi
call fib
movq %rax, %rbx
movq -24(%rbp), %rax
subq $2, %rax
movq %rax, %rdi
call fib
addq %rbx, %rax
.L3:
addq $24, %rsp
popq %rbx
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE5:
.size fib, .-fib
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE6:
.size main, .-main
.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
.section .note.GNU-stack,"",@progbits
我的问题是:
为什么我们将堆栈指针减 24 subq $24, %rsp
,?正如我所看到的,在最初的两次推送之后,我们只在堆栈中存储一个元素,第一个参数n
in 。%rdi
那么我们为什么不直接将堆栈指针减 8,然后移动n
到-8(%rbp)
? 所以
subq $8, %rsp
movq %rdi, -8(%rbp)
解决方案
GCC 没有完全优化-O0
,甚至没有使用它的堆栈。(这可以通过使堆栈的某些使用对人类更透明来帮助调试。例如,如果对象a
的活动生命周期(由程序中的使用定义b
,c
而不是由C 标准中的生命周期)-O3
,但可能在堆栈中单独保留了位置-O0
,这使得人们更容易看到在汇编代码中使用的位置,a
浪费的 16 个字节可能是副作用这个,因为这些空间可能被保留用于这个小功能没有使用的某些目的,例如在需要时保存某些寄存器的空间。)b
c
推荐阅读
- r - 如何在 R 中创建变量时修复因子水平顺序
- html - 保持占位符增加字体大小并垂直居中
- python - 为本地转换收集数据帧时出现 OOM 错误
- swift - 将 cookie 传递给 WKWebView / SFSafariViewController?
- c++ - What is the correct way to implement derived classes with arbitrary combinations of common virtual function implementations?
- spring-cloud - Spring-cloud-contract stubrunner.jar change tomcat port
- html - Multilevel Drop-down not able to implement using bootstrap and on hover
- javascript - How can I compare two select menus with JavaScript?
- javascript - Getting asynchronously loading external HTML data with JQuery
- phpdesktop - 如何每次都获得相同的 URL?