前言
在回顾之前学习CSAPP内容时,发现第三章内容还是没深入理解,所以今天重新学习了一遍。
- 在编译一段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的存在,因此减少了指令数。
从今天的学习中可以看到汇编语言与高级语言中的关联,与优化后底层汇编代码的变化。