标签:
攥写人:李鹏举 学号:20132201
( *原创作品转载请注明出处*)
( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 )
实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同)
使用gcc –S –o main.s main.c -m32命令编译成汇编代码。
代码如下:
int g(int x) { return x + 8; } int f(int x) { return g(x); } int main(void) { return f(12) + 2; }
实验过程及截图:
1.进入实验楼,进入Code文件夹,单机右键直接建立 lipengju.c文件

2.打开文件并将相应代码写入,保存并退出

3.
使用gcc -S -o lipengju.s lipengju.c -m32 将lipengju.c编译成汇编代码lipengju.s

4.打开lipengju.s文件,会看到机器转换之后的汇编代码

5.将以"."开头的行删去,得到纯净的汇编代码


实验分析:栈的变化
1.
开始时eip指向18行,ebp esp都在堆栈0的位置

2.执行eip处的指令,pushl %ebp,将ebp值压栈

3.eip执行至19行,
movl %esp,%ebp,将esp值赋给ebp

4.eip执行至20行,
subl $4,%esp,将esp向下移一格

5.movl $24,(%esp),将24存入此时esp所指的位置

6.
call f,调用f函数,将eip 23压栈,此时eip指向f函数

7.pushl %ebp,将此时ebp值压栈

8.
movl %esp,%ebp,将esp值赋给ebp

9.subl $4,%esp,esp向下移一格
10.movl 8(%ebp),%eax,将ebp向上两格装的值赋给eax,所以此时eax=24
11.movl %eax,(%esp),将eax的值赋给esp此时指向的格
12.call g,调用g函数,eip 15压栈,此时eip指向g函数

13.
pushl %ebp,将此时ebp值压栈
14.movl %esp,%ebp,将esp值赋给ebp
15.movl 8(%ebp),%eax,将ebp上两格的装的值赋给eax,此时eax=33
16.addl $11,%eax,给eax加11,加上之后,eax=44
17.popl %ebp,弹栈,此时ebp赋值为栈中所存的ebp 4,esp缩进退一格
18.ret,弹栈,此时eip赋值为栈中所存eip 15,esp缩进一格
19.leave(leave指令为如下步骤)
leave
movl %ebp,%esp
popl %ebp
所以此时堆栈指针会变为

20.ret,弹栈,此时eip指向弹栈的eip 23
21.addl $1,%eax,将eax加1,此时eax为45
22.leave操作(
先 movl %ebp,%esp,将ebp赋值给esp
)

此为C语言过程中所有的堆栈变化。
实验体会:
本次实验最重要的体会就是感受到了linux系统汇编语句和windows中汇编语句的不同,但是堆栈变化的分析基本相同,但是了解这些过程和一步步了解这些步骤并画出来还是不同的,通过这样的分析让我更加了解了linux汇编语言的变化。
并且通过本次实验了解了实验楼的用法,知道怎样在linux中建立C文件,并且将一段编好的C语言代码编译成汇编语言,总之这是对我今后Linux学习的一个很好的开始。
标签:
原文地址:http://www.cnblogs.com/puputongtong/p/5225332.html