它是堆栈框架吗?
Is it a stack frame?
我不明白为什么 gcc 甚至为此代码触及 %esp:
int foo(char *);
int bar(char** a)
{
if (!a[1]) {
return 1;
}
if (foo(a[1]) == -1) {
return 1;
}
return 0;
}
生成 -O2
:
bar:
.LFB0:
.cfi_startproc
movq 8(%rdi), %rdi
movl , %eax
testq %rdi, %rdi
je .L7
subq , %rsp
.cfi_def_cfa_offset 16
call foo
cmpl $-1, %eax
sete %al
addq , %rsp
.cfi_def_cfa_offset 8
movzbl %al, %eax
.L7:
rep ret
而且 clang 通过在开始时将 %rax
推入 %rax
然后将其弹出到 %rdx
.
来做一些甚至疯狂的事情
是分配栈帧吗?这与这些 .cfi
指令有关吗?
因为在x64中,栈必须是16字节对齐的,调用指令使栈失衡。这个特定的代码不关心任何事情,但编译器不知道 foo 关心的任何指令。
事实上,它总是在调用时未对齐,应该在序言代码中重新对齐;然而,优化器将 prolog 和 epilog 破坏得面目全非。
我不明白为什么 gcc 甚至为此代码触及 %esp:
int foo(char *);
int bar(char** a)
{
if (!a[1]) {
return 1;
}
if (foo(a[1]) == -1) {
return 1;
}
return 0;
}
生成 -O2
:
bar:
.LFB0:
.cfi_startproc
movq 8(%rdi), %rdi
movl , %eax
testq %rdi, %rdi
je .L7
subq , %rsp
.cfi_def_cfa_offset 16
call foo
cmpl $-1, %eax
sete %al
addq , %rsp
.cfi_def_cfa_offset 8
movzbl %al, %eax
.L7:
rep ret
而且 clang 通过在开始时将 %rax
推入 %rax
然后将其弹出到 %rdx
.
是分配栈帧吗?这与这些 .cfi
指令有关吗?
因为在x64中,栈必须是16字节对齐的,调用指令使栈失衡。这个特定的代码不关心任何事情,但编译器不知道 foo 关心的任何指令。
事实上,它总是在调用时未对齐,应该在序言代码中重新对齐;然而,优化器将 prolog 和 epilog 破坏得面目全非。