从汇编语言角度看C语言代码,理解计算机如何工作

来源:互联网 发布:js打开无导航栏新窗口 编辑:程序博客网 时间:2024/06/02 07:14

作者:董涛 

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-10000290

 

本文通过将一段C语言代码转换为汇编语言代码,利用更接近机器码的汇编码讲述C语言程序如何在计算机内部运行的,从而更深刻的理解冯诺依曼的存储程序式计算机的架构思想。

我们的工作平台是实验楼网站(www.shiyanlou.com)提供的虚拟Linux操作系统。

首先,我们创建一段C语言代码,如下图所示:

 

http://simplecloud.qiniudn.com/28929328d19122d7aae26577be36ba20

 

然后,我们在Linux的shell页码将这段C格式的main.c文件保存为汇编格式的main.s文件,并用32位的汇编命令打开,如下图所示:

 

 

打开汇编格式的代码,如下图所示:

 

 

好了,以上的第一幅图和第三幅图分别对应程序的C语言代码和汇编语言代码,现在我们以汇编语言为认知工具,看看程序是如何在计算机内部运行的:

首先,计算机的IP指针指向main段,通过pushl %ebp;  movl %esp, %ebp; 这两行命令,将扩展基址指针寄存器ebp内的值作为栈帧的栈底地址压入栈,同时将栈顶的地址%esp赋值为%ebp,。第二步,通过subl $4, %esp;将栈顶值向下扩展4个字节,这里需要注意的是栈的编址是自上而下,从大到小的,也就说先进栈的占据大的地址,后面进栈的占据相对小的地址,第二步完成后,栈可以容纳4个字节32个字符的数据了。第三步,通过命令movl  $10,  (%esp)将数据10写入栈顶esp。第四步,通过call  f;将程序跳转至f段,同时eip指针指向程序的下一行(即第23行),以备f程序段完成后,回归主程序。

接下来,看看f段程序,关于pushl,movl subl call等语句的含义,可以参考对main段的阐述,在f段中通过call命令调用了g程序,同理对于g程序的工作过程指令可以参考对main段的阐述,这里需要注意的是,popl命令和leave命令,popl命令是释放堆栈地址的,leave命令等同于如下两行代码的作用:movl  %ebp,  %esp;  popl %ebp.

好了,执行完f段和g段后,程序通过epi指针回到main程序的第23行,通过addl  $2,  %eax命令,将2加入到%eax中,并保存在eax中,这就是我们所要的最终结果。

由以上过程可以看出,程序在计算机中的运行是通过栈的方式不断的调用函数最会回归至主函数,得出我们所要的结果的。

0 0
原创粉丝点击