Linux 内核分析 之一:How Computer Works 实验
说明 欧长坤 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 这学期学校恰好有操作系统的课程,上个学习就开始寻思研究研究Linux内核代码,恰好MOOC有这个课程,遂选了此课。
一、实验过程 首先,我们将C语言代码利用编译器编译成汇编代码,下面是C语言代码:
1 2 3 4 5 6 7 8 9 10 11 12 int g(int x) { return x + 999; } int f(int x) { return g(x); } int main(void) { return f(0) + 1; } 值得一提的是,事实上在我们没有使用标准C语言库的时候,可以不引用任何头文件(比如#include 就是不需要的)。显然,上面的代码并没有用到任何库函数。
通过gcc的功能,我们可以自定义编译参数来控制编译选项,我们为了让上面的代码编译成32位汇编代码,使用下面的命令:
1 gcc -S -o main.s main.c -m32 其中我们的编译环境为Mac OS X 10.10,所以提供的编译环境为64位编译环境,所以使用了参数-m32将C语言代码编译为32位汇编代码,而-S表示只是编译不汇编,生成汇编代码。而-o file表示将结果输出到file中。
我们可以观察生成的.s文件,如下图所示。
bwlq分别代表8、16、32、64位寄存器操作,所以我们可以看到这里的汇编指令l结尾,说明这些指令都是操控32位寄存器长度。
我们保留纯汇编代码的部分,得到如下的汇编代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 _g: pushl %ebp movl %esp, %ebp pushl %eax movl 8(%ebp), %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax addl $999, %eax ## imm = 0x3E7 addl $4, %esp popl %ebp retl _f: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax movl %eax, (%esp) calll _g addl $8, %esp popl %ebp retl _main: pushl %ebp movl %esp, %ebp subl $24, %esp movl $0, %eax movl $0, -4(%ebp) movl $0, (%esp) movl %eax, -8(%ebp) ## 4-byte Spill calll _f addl $1, %eax addl $24, %esp popl %ebp retl 下面我们来分析这段代码的行为。