运行环境:实验楼
/*main.c*/
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
/*Makefile*/
all:
gcc –S –o main.s main.c -m32
/*main.s*/
.file "main.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $3, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size f, .-f
.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 $4, %esp //栈顶
movl $8, (%esp) //将8赋给栈顶
call f
addl $1, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
gcc –o main main.c -m32 //可以编译为可执行文件
//然后在命令行下
./main 就开始执行了
//这个过程大概是bash解析了命令行.
并fork并exec了main
将main从设备块中读取到高速缓冲块中,然后拷贝到用户空间的对应段上.?,并建立栈顶esp和栈底ebp和eip
//栈顶在栈底下面,中间无间隔,eip指向main中的 pushl %ebp
然后从main开始运行,在栈内?
//栈内的哪个地址?
假设栈内的地址为0xbfe5 d38f,栈向下增长
/*用户栈*/
/*从高到*/
主程序的参数
主程序调用后的返回地址
第0帧地址
局部变量
fun1的参数
fun1调用后的返回地址
第1帧地址
局部变量
汇编代码解析
main
- main标号内的pushl执行之前的状态
- pushl %ebp
下面的图表示是上面的语句执行完之后的状态
即
下图表示的是 pushl %ebp 后的状态
- movl %esp, %ebp
- subl $4, %esp
- movl $8, (%esp)
- call f
f
- pushl %ebp
- movl %esp, %ebp
- subl $4, %esp
- movl 8(%ebp), %eax
该行没有改变栈,只是将(ebp-8)地址内的值(8)付给了eax
- movl %eax, (%esp)
- call g
g
- pushl %ebp
- movl %esp, %ebp
- movl 8(%ebp), %eax
该行没有改变栈,只是将(ebp-8)地址内的值(8)付给了eax
- addl $3, %eax
改行没有改变栈,只是将eax加了3,此时为11
- popl %ebp
- g:ret
f
- f : leave
- f:ret
main
- addl $3, %eax
此时没改变堆栈,只是将eax中的值加了3,此时为14
- leave
- ret
注意:
这里面需要注意的是%eax是独立于栈存在的,所以不会消失,所以返回值都存在%eax寄存器中
栈分为四种,这里面分析的栈是满减栈,另外还有空减栈,满增栈,满减栈