从汇编角度来解析c程序的运行过程


           程  序 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

          学过计算机的都知道,我们将c语言编译以后就成了汇编语言,汇编语言作为一种更加接近计算机的语言,分析它有助于我们理解计算机的工作过程。在Linux系统中,通过gcc –S –o main.s main.c语句即可将c语言文件转换成汇编文件。

      学好汇编离不开分析汇编文件,下面我们来结合一个小的c语言程序,将其编译成汇编语言,结合堆栈变化,一起来看看c语言的执行过程。在开始讲解前,我们一起来了解一下基本知识。

esp:指针寄存器,指向栈顶。
ebp:指针寄存器,指向栈底。
eip:指令寄存器,存放下一条执行语句地址。
eax:数据暂存寄存器,暂时存放相应的执行结果。
movl:移动指令,将前面的值放入后面,注意此处有多种寻址方式。
subl:汇编减法语句,后面减去前面数值放入后面寄存器。
addl:汇编加法语句,后面加上前面数值放入后面寄存器。
leave:汇编语句,相当于movl %ebp ,%esp ; popl %ebp两条语句的结合。
enter: 汇编语句,相当于 pushl %ebp;movl %esp,%ebp 两条语句的结合。
popl:汇编出栈语句,相当于movl (%esp),%eax; addl $4 ,%esp两条语句的结合。
pushl:汇编压栈语句,相当于 subl $4,%esp;movl %eax,(%esp) 两条语句的结合。
call:汇编调用语句,相当于pushl %eip(*) ; movl $0x12345,%eip(*)两条语句的结合。
ret:汇编返回语句,相当于Popl %eip(*)。


下面开始介绍c语言变成汇编语言后是怎么运行的。
首先我们来看c语言,凡是有一定c语言基础知识的人,理解下面一段c语言程序代码都不是很困难。c语言代码如下

1  int g(int x)
2  {
3    return x+4;
4  }
5
6  int f(int x)
7  {
8    return g(x);
9  }
10
11 int main(void)
12 {
13   return f(5)+1;
14 }

        结果很简单,我们知道结果为10。下面来看看这段代码转换成汇编语言后是一个什么情况。源汇编代码较为复杂,因为其中保留了很多链接信息,但是那些语句不会执行,为了简便,我将里面负责链接的语句删除了。上面c语言的程序的汇编代码如下
1 g:
2	pushl	%ebp
3	movl	%esp, %ebp
4	movl	8(%ebp), %eax
5	addl	    $4, %eax
6	popl  	%ebp
7	ret
8 f:
9	pushl	%ebp	
10	movl	%esp, %ebp
11	subl 	$4, %esp		
12	movl	8(%ebp), %eax
13	movl	%eax, (%esp)
14	call	    g
15	leave
16	ret
17 main:
18	pushl	%ebp
19	movl	%esp, %ebp
20	subl 	$4, %esp
21	movl	$5, (%esp)
22	call  	f                                        
23	addl 	$1, %eax
24	leave
25	ret

        为了方便讲解,我们来约定一些规则,约定规则如图1所示,假设下面是此段c程序的堆栈段,我们用逻辑地址0-10表示实际物理地址,然后esp,ebp两个寄存器指针指向0处,现在开始运行了,我们用表格动态模拟堆栈变化。

  

 

      下面这张表格记录了程序的运行过程。


                  

                                                                        表1.汇编代码运行时的寄存器及堆栈变化表


            从表1,我们能很清楚的看到汇编程序的运行流程,最后我们可以看到,程序的运算结果就是10。

至此,我们了解清楚了c语言编译成汇编语言后在机器平台上面的运行流程和方式。下面,我来演示一下Linux系统下的实现。


 

                                                                                                                   图2.在Linux环境下进入Code文件夹


 

                                                                                                                    图3.用vi编辑器进行编辑c文件



 

                                                                                                                                     图4.编写的c文件


 

        图5.运行指令进行编译


 
                          图6.打开汇编代码文件
 

                        

  图7.保留我们需要分析的代码段



         总结:通过以上过程,我们应该对计算机是怎么工作的有一定的了解。人类的思维活动通过相应的高级语言编写成代码,输入到计算机中,计算机根据规则将高级语言代码转化成汇编语言,然后通过取址、译码、运算、输出结果等步骤将人类赋予的任务完成。从人类抽象思维到计算机具体的加减乘除的转化,再将一串二进制数字转化为人类能够理解的符号,即是计算机的意义,这其中的转化流程即是计算机的工作过程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值