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

计算机是如何解读高级语言的

2016-02-27 21:02 375 查看
大家都知道,C语言是一种应用非常广泛的高级语言,而且标准的C语言程序可以在很多电脑平台上进行编译,但是大家是否知道计算机是怎么解读C语言的呢?
下面我通过一个小小的例子来为大家分析一下:首先是编写一段简单的C语言程序,如下图所示:


然后我们把它反编译成汇编语言,因为汇编语言是最接近机器语言的,如图:


接下来我们通过这段汇编语言来分析这段C语言是怎么运行的:

g:

1 pushl %ebp //寄存器esp由地址1976开始-4,再将寄存器ebp的内容放入esp;

2 movl %esp, %ebp ///将esp的值放入ebp中,即让ebp=1972;

3 movl 8(%ebp), %eax //将ebp+8=1980中的内容放入寄存器eax中,即eax=9;

4 addl $5, %eax //将当前寄存器eax中的内容+5,即eax=14;

5 popl %ebp //将当前esp中的内容存到寄存器ebp中,即ebp=1984,esp+4=1976;

6 ret //相当于popl %eip,将当前esp的内容存到eip,即eip=13,跳转到地址13;

f:

7 pushl %ebp //寄存器esp由地址1980开始-4,再将寄存器ebp的内容放入esp;

8 movl %esp, %ebp //将esp的值放入ebp中,即让ebp=1984;

9 subl $4,%esp // esp再-4,即esp=1980;

10 movl 8(%ebp),%eax //将ebp+8=1992中的内容放入寄存器eax中,即eax=9;

11 movl %eax,(%esp) //将eax中的内容9存入当前esp中;

12 call g //可以理解为pushl %eip; movl $g, %eip,即将当前寄存器eip的值13入栈,将g函数所在的地址1存入eip寄存器中,然后跳转到g函数;

13 leave //相当于movl %ebp,%esp;popl %ebp;将ebp的内容存到esp中,即esp=1984,再将当前esp中的内容存到寄存器ebp中,即ebp=1996,esp+4=1988;

14 ret //将当前esp的内容存到eip,即eip=20,跳转到地址20;

main:

15 pushl %ebp //寄存器esp由栈底2000开始-4,再将寄存器ebp的内容放入esp;

16 movl %esp, %ebp //将esp的值放入ebp中,即让ebp=1996;

17 subl $4,%esp //esp再-4,即esp=1992;

18 movl $9, (%esp) //将9存入esp中,即栈地址1992中存入9;

19 call f //可以理解为pushl %eip; movl $f, %eip,即将当前寄存器eip的值20入栈,将f函数所在的地址7存入eip寄存器中,然后跳转到f函数;

20 addl $3, %eax //将当前寄存器eax中的内容+3,即eax=17;

21 leave //将ebp的内容存到esp中,清空堆栈;

22 ret

又因为X86是满递减堆栈,所以堆栈的工作方式是先往低地址增长,再进行操作,首先从main函数开始分析,见函数注释;堆栈的变化见下表1-1:



实验总结:

由于汇编语言是最接近机器语言的,所以高级语言需要通过编译器编译成汇编语言,然后再由计算机翻译成机器语言开始运行操作的。而程序的执行都是通过一些寄存器与存储器进行交互操作完成的。上面的例子就是一个很好的说明

作者:叶涛

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐