您的位置:首页 > 理论基础

通过汇编一个简单的C程序,分析汇编代码理解计算机工作原理

2016-02-28 12:08 726 查看
徐晨 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000



这是一个简单的C语言程序,我们为了通过汇编语言分析其调用过程,首先将其编译成汇编代码。本实验中我们采用x86-32汇编,命令如下:

gcc -S -o main.s main.c -m32


我们去掉汇编文件中用于链接过程的代码,得到下面程序:



分析一下该程序,该程序的最初入口为main, 我们从line18开始。

18  pushl %ebp
19  movl %esp, %ebp




进入main函数中,我们首先保存现场,新开一个栈帧。具体做法为line18&19,将原来的ebp压栈,然后讲其赋值为esp,此时,新的栈帧中形成了一个空栈。

line20&21中,main函数向下移动栈顶4个byte,并将操作数23放入栈中。然后在line22调用f,对比C代码我们知道23实际上是调用函数f的参数。
20     subl    $4, %esp
21     movl    $23, (%esp)
22     call    f


call f命令可以理解为压栈eip当前值(line23),然后修改eip到f的地址(9) (注意这里是伪指令,因为eip的值不能显示),所以接下来CPU的执行进入函数f。

push %eip
movl $9 %eip

在函数f中,我们首先做的依然是保存现场,新开一个栈帧(line9&10),和在main函数中一样。之后我们向下移动栈顶4个byte(line11),并将ebp+8地址的值传递给eax(这个值就是23)(line12),接着将eax寄存器中的值放入esp地址指向的空间中(line13),我们可以看到(line13&14)和(line21&22)非常相似,实际上这都是调用一个含参函数的过程,不同之处在于main函数中我们直接将操作数放入栈顶(注意这里的栈顶是针对调用f之前而言),而在f中我们讲寄存器中的值放入栈顶。

9     pushl   %ebp
10     movl    %esp, %ebp
11     subl    $4, %esp
12     movl    8(%ebp), %eax
13     movl    %eax, (%esp)
14     call    g


line14我们调用函数g,这里和调用f的过程一样,压栈eip,将eip赋值为g的地址(line2)。
进入函数g,依然保存现场,新开栈帧(前面已分析,不再赘述)。line4我们看到,实际上是函数g在取它的参数x(也就是23),line5开始了该程序第一次对操作数的运算,将参数x+9(23+9=32)放入eax中(注意x86-32中eax是默认存储返回值的寄存器)。我们可以看到此时该函数的堆栈情况如下所示:



然后该函数直接pop %ebp,这是因为新栈帧中并没有压入任何内容,所以pop了以后,ebp就指向了f调用g之前的栈底。line7中的ret作用相当于popl %eip,也就是说g函数已经执行完了,返回到f函数中去(line15)。

2     pushl   %ebp
3     movl    %esp, %ebp
4     movl    8(%ebp), %eax
5     addl    $9, %eax
6     popl    %ebp
7     ret




我们看到line15是一条leave命令,该命令相当于movl %ebp %esp, pop %ebp,实际上我们可以理解为f函数此时已经不再需要它自己的栈帧,所以它pop了以后,ebp指向了main调用f之前的栈底。line16中的ret作用相当于popl %eip,也就是说f函数已经执行完了,返回到main函数中去(line23)。

15     leave
16     ret

回到main函数(line23)中,我们开始了对操作数的第二次运算(此前eax的值32),我们将该值加7并放入eax中(32+7=39)。接下来main函数执行leave,放弃自己的栈帧,将ebp指向调用main之前的栈底(该值由操作系统管理),接着line25执行ret,也就是main函数已经执行完了,返回到调用main的函数之中(操作系统管理)。

23     addl    $7, %eax
24     leave
25     ret




至此,整个程序执行完毕。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: