欢迎使用CSDN-markdown编辑器

计算机程序的运行

本文将通过一个C语言的程序来介绍以下几个概念:
- 汇编语言
- 函数调用
- 计算机的运行过程
首先,我们先写一个简单的C语言程序,如下:

int g(int x)
{
      return x +100;
}

int f(int x)
{
      return g(x);
}

int main(void)
{
      return f(200) + 300;
}

然后我们把源程序编译成一个汇编语言,指令如下

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

这样,我们就得到一个汇编文件,为如下截图:

为了便于理解,我们把一些为了方便编译器工作的代码给删除,结果如下:

g:
    pushl   %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %eax
    addl    $100, %eax
    popl    %ebp
    ret
f:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    g
    leave
    ret
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    $200, (%esp)
    call    f
    addl    $300, %eax
    leave
    ret

接下来,我们将以这个文件来说明上面说的几个概念

汇编语言

汇编语言是一种低级语言,接近机器指令,但还是非常方便,效率强大。汇编语言有2种语言,一种是Intel语法,一种是AT&T格式,Linux系统中一般都用的是AT&T语法。AT&T语法的一个特点就是源操作数在前,目的操作数在后,恰好和Intel语法相反,常见的汇编指令有:
- mov:传送指令
- push和pop:压栈和出栈指令
- call和ret:后面会说到
- sub和add:减法和加法指令

函数的过程调用

程序使用程序栈来支持过程调用,用栈来传递过程参数,存储返回信息等等。程序为每个过程分配的那部分栈称为栈帧。
一般一个过程调用的前两句汇编代码为:

pushl %ebp
movl %esp,%ebp 

进行栈帧信息的存储,方便过程调用结束后返回。

过程调用结束之前的最后两句代码一般为:

leave   //等价于这两句代码 movl %ebp,%esp 
        //popl %ebp
ret

这样就顺利完成了一个函数的调用及返回。其他的比如参数的传递是通过在调用之前进行压栈传递的,如在示例代码中,main调用f是这么做的

subl $4, %esp
movl $200, (%esp)
call f

先把esp减4,再把200放到esp所指向的位置,其实就相当于直接把200压栈了。然后call f 调用f函数。基本上一个过程调用就是先压参数,调用,保存栈帧,然后返回的。

计算机程序的运行

现在的计算机都是冯诺一曼结构,其核心就是存储程序思想,凡是图灵机所能做的事情,计算机就可以做。当然,凡是图灵机不能做的事情,不管是现在还是未来的计算机都不能做。计算机是机器,它只认识二进制01,用这些一串串的01构成了一条条指令,它有个eip寄存器,计算机就把这个寄存器所指向位置的指令取出来,然后一条条的执行,然后完成了我们所要做的任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值