汇编一个简单的C程序

说到计算机,大家都知道现代计算机都是由冯诺依曼体系结构组成的,也就是储存程序计算机。让我先从它的工作模型说起。

冯诺依曼体系结构由运算器、控制器、存储器、输入设备和输出设备组成,其中指令与数据同时存放在储存区中。它们工作时的状态如图所示:汇编一个简单的C程序_第1张图片

我们的程序运行时,一般都是操作系统当做程序与硬件之间的“中间人”,而应用程序与操作系统之间的交互,则依赖于ABI(Application Binary Interface)。当然,我的水平还远不到读写二进制机器码的程度,自然也不会深究这个ABI。

下面,我们来对一个简单的C程序进行汇编,C语言源代码如下:

int func1(x)
{
    return x + 10;
}

int func2(x)
{
    return func1(x);
}

int main(int argc, char * argv[])
{
    return func2(20) + 8;
}

笔者使用了实验楼的Linux环境来实现获得程序编译所得的X86(32位)汇编程序,链接在此: https://www.shiyanlou.com/courses/195

使用gcc即可,命令如下:

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

其中,-S表示在程序编译期间,在生成汇编代码后停止,-o参数输出汇编代码文件main.s,而-m32自然就是生成32位的汇编代码。

我们打开main.S,能看到汇编代码(部分)如下:汇编一个简单的C程序_第2张图片

其中以.开头的命令都是作为链接的命令,我们把以.开头的行全部删除,得到汇编代码如下:

func1:
    pushl    %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %eax
    addl    $10, %eax
    popl    %ebp
    ret

func2:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    func1
    leave
    ret

main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    $20, (%esp)
    call    func2
    addl    $8, %eax
    leave
    ret

至此,我们就完成了对程序的汇编,然后我们来看看程序的执行过程:

在堆栈增增减减的过程中,计算机也不断的取指令、执行指令,完成对程序的执行。



Author : 陈政 / arc001

原创作品转载请注明出处 《Linux操作系统分析》MOOC课程

你可能感兴趣的:(汇编,C语言,堆栈,计算机体系)