计算机工作过程的理解

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

    通过视频的学习,认识到计算机工作的过程跟我们读使用高级语言编写的代码流程基本上是一致的,只不过计算机不能识别高级语言,只能识别像汇编语言、二进制代码等低等语言,其中了解到汇编语言实际上是对二进制代码的符号表示,汇编语言更贴近底层技术。
   计算机在执行用高级语言编写的代码的时候,首先要通过便已将其变为计算机可以识别的汇编语言,进而通过cpu和寄存器的相互结合逐条执行计算机指令。
   如下c语言编写的代码:
 int g(int x)
{
  return x +4;
}
int f(int x)
{
  return g(x);
}
int main(void)
{
  return f(4)+2;
}
用命令gcc -S -o main.s main.c -m32,删除没有实际作用的以点开头的汇编代码行,我们可以得到纯净的汇编代码,如链接:http://www.shiyanlou.com/u/NTY0MzE5MDQ2MjI3/result/1所示,此处的汇编语言与单片机、微机原理和数据结构上讲的
 原理是一样的,只不过跟单片机上的汇编格式不一样,用到的主要的寄存器有:ebp(堆栈底指针)、esp(堆栈顶指针)、eip(始终指向下一条将要执行的指令),eax(存放数据默认的寄存器,也是与上一级函数进行交互的默认寄存器),用到的汇编指令主要有:movl、addl、subl、ret、leave、pushl、popl等,与之前学的单片机上使用的汇编指令很大的区别就是各指令中的源寄存器与目的寄存器正好相反,还有就是这里通过在相应指令上添加l指出了是32位系统。具体的执行过程如下:
1)pushl %ebp
   movl %esp,%ebp
刚开始可以认为ebp、esp指向同一个地址(即此时是空栈),在这种假设下,这2条指令首先是esp指向的地址减去4个字节,并且紧接着esp、ebp同时指向同一个地址;
2)movl 8(%ebp),%eax
     addl $4,%eax
     popl %ebp
     ret
   这4条指令首先是把ebp+8的结果强制转换为地址类型,并且取该地址的内容给eax(在这里是4),然后是4+4=8,把结果8放到eax中,接下来就是把esp中的内容弹出到ebp中,执行ret。
3)pushl %ebp
   movl %esp,%ebp
操作过程同1),只不过此时不是空栈开始。
4) subl $4,%esp
    movl 8(%ebp),%eax
    movl %eax,(%ebp)
    call g
    leave
    ret
这些指令首先是把esp的指向减去4个字节,紧接着把ebp+8的结果强制转换为地址类型,并且取该地址的内容给eax,接下来就是把eax中的内容交给ebp指向的地址中,调用函数g,即执行g函数,此时把原来的eip(即call g 的下一条指令leave)压栈,把g函数的地址给eip,执行完毕再把压入的eip的内容弹出到eip中继续执行leave、ret指令。
5)pushl %ebp
   movl %esp,%ebp
操作过程同1),只不过此时不是空栈开始。
6)subl $4,%esp
   movl $4,(%esp)
   call f
   addl $2,%eax
   leave
   ret
这些指令同4)很相似,不同之处就在于把eax(此时是8)加上了2,使得eax的内容成为8+2=10,其它命令一样。
 
 
posted @ 2015-03-08 22:24  浩渺之中一粒粟  阅读(708)  评论(0编辑  收藏  举报