在学习C 汇编中发现了一个奇怪的现象,如下
int foo1(int m,int n)
{
int p=m*n;
return p;
}
int foo(int a,int b)
{
int c=a+1;
int d=b+2;
int e=foo1(c,d);
return e;
}
int main()
{
int result=foo(3,4);
return 0;
}
生成的汇编代码如下
.file "foo.c"
.text
.globl foo1
.type foo1, @function
foo1:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl 8(%ebp), %eax
imull 12(%ebp), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size foo1, .-foo1
.globl foo
.type foo, @function
foo:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl 8(%ebp), %eax
addl $1, %eax
movl %eax, -12(%ebp)
movl 12(%ebp), %eax
addl $2, %eax
movl %eax, -8(%ebp)
pushl -8(%ebp)
pushl -12(%ebp)
call foo1
addl $8, %esp
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size foo, .-foo
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
pushl $4
pushl $3
call foo
addl $8, %esp
movl %eax, -4(%ebp)
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
代码使用32位编译的,一个int的字节是4
把上面的帧栈画出来
帧栈 |
---|
ebp(main) |
4 (para b in foo) |
3 (para a in foo) |
ret(return of foo) |
ebp(foo) |
s[fool return value](local var in foo) |
d(6)[b+2](local var in foo) |
c(4)[a+1](local var in foo) |
d(para var in foo1) |
c(para var in foo1) |
ret(return of foo1) |
ebp(foo1就是这里) |
p(laocao var in foo1) |
null |
null |
null |
汇编中有一行
subl $16 %esp
也就是开辟了 四”块”栈区,但实际上,foo1函数中只有一个local variable —– p
后询问大佬得知了如标题,同时又认识了一本book:)
图片出自《深入理解计算机系统》