标签:
本文将通过编译器生成的汇编代码分析C程序在IA-32体系PC上的运行流程
实验环境: gcc 4.8.2
C代码如下
int g(int x)
{
return x + 1;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(2) + 3;
}
使用编译命令gcc -S -O0 -o main.s main.c -m32
编译出汇编文件,如下
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $1, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $2, (%esp)
call f
addl $3, %eax
leave
入口点位于main,由main开始分析
进入main以后的第一个函数调用f(x)
最后一个函数调用g(x)
C语言程序在IA-32机器上的运行过程中,最重要的几条指令即push/pop,call/ret,其中push/pop实现了栈的基本操作,call/ret维护了函数的调用栈,确保了函数调用流程的连续
使用ddd抓了两张call前后的eip变化,可以很清晰的看出eip在call时的非线性改变
最后再看一下编译器优化可以做到的效果,以gcc -S -O3 -o test.s test.c -m32
编译上述代码,得到的汇编如下
g:
movl 4(%esp), %eax
addl $1, %eax
ret
f:
movl 4(%esp), %eax
addl $1, %eax
ret
main:
movl $6, %eax
ret
可以看见编译器直接把main函数的结果算出来当做立即数返回了。。还是很强大的。。f和g这种简单函数也没有重新设置栈底,而是直接采用了变址寻址,提升了运行效率
云课堂作业
吴韬,原创作品转载请注明出处,《Linux内核分析》MOOC课程
标签:
原文地址:http://www.cnblogs.com/current/p/4321525.html