深入学习计算机系统第三章

Hello world,hello blog!

Posted by 吴柚 on May 6, 2019

前言

在回顾之前学习CSAPP内容时,发现第三章内容还是没深入理解,所以今天重新学习了一遍。

  1.  在编译一段C语言程序的过程中,其实做了很多步骤,比如预编译处理、编译处理、汇编处理以及链接处理。我们要了解的汇编语言,就是在编译处理后的产物。因此我们可以在GCC的编译器当中加入一些参数来控制它只生成汇编语言,而不进行汇编处理和链接处理。

  以下面这一段简单的C语言代码,假设为sum.c。

int simple(int *xp,int y){
    int t = *xp+y;
    *xp=t;
    return t;
}

使用GCC编译器加-S参数来编译这段代码,最终我们可以得到一个sum.s的文件,我们使用cat来查看一下这个文件。.file “sum.c”

 .text
.globl simple
.type    simple, @function
simple:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    8(%ebp), %eax//这一步是从主存取变量xp
    movl    (%eax), %eax//取*xp的值
    addl    12(%ebp), %eax//计算*xp+y,并存到%eax寄存器
    movl    %eax, -4(%ebp)//将*xp+y赋给变量t
    movl    8(%ebp), %eax//再取xp
    movl    -4(%ebp), %edx//取t
    movl    %edx, (%eax)//执行t->*xp
    movl    -4(%ebp), %eax//将t放入%eax准备返回
    leave
    ret
    .size    simple, .-simple
    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

可以通过GCC控制编译器的优化级别,因此我们使用另外一种方式来编译一下sum.c,我们在-S的基础上再加一个-O1的参数。之后使用cat打开sum.s文件。

.file    "sum.c"
    .text
.globl simple
    .type    simple, @function
simple:
    pushl    %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %edx//取xp
    movl    12(%ebp), %eax//取y
    addl    (%edx), %eax//计算*xp+y并存到%eax寄存器,准备返回
    movl    %eax, (%edx)//将*xp+y存入*xp
    popl    %ebp
    ret
    .size    simple, .-simple
    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

可以很明显的看出,汇编指令的数目急剧减少,这里的优化主要是去掉了变量t的存在,因此减少了指令数。

从今天的学习中可以看到汇编语言与高级语言中的关联,与优化后底层汇编代码的变化。