通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
1.实验过程
首先打开实验楼的环境,编写c代码,并保存为main.c
然后打开命令行,将其编译为汇编代码。
打开汇编代码文件。
将其中.开头的代码删掉,得到便于分析阅读的汇编代码文件。
二、汇编代码的工作过程中堆栈的变化
具体汇编代码如下:
1 g:
2 pushl %ebp
3 movl %esp, %ebp
4 movl 8(%ebp), %eax
5 addl $14, %eax
6 popl %ebp
7 ret
8 f:
9 pushl %ebp
10 movl %esp, %ebp
11 subl $4, %esp
12 movl 8(%ebp), %eax
13 movl %eax, (%esp)
14 call g
15 leave
16 ret
17 main:
18 pushl %ebp
19 movl %esp, %ebp
20 subl $4, %esp
21 movl $9, (%esp)
22 call f
23 addl $1, %eax
24 leave
堆栈的变化如下:
三、总结计算机是如何工作的
3.1 硬件
从硬件的角度上说,计算机是冯诺依曼体系结构,也可以称为存储程序计算机,核心结构如图所示:
1.在主存中依次放着各条指令和数据。
2.CPU用来解释这些指令,执行相应的任务。
除此之外,硬件中还有一系列的寄存器用以支撑CPU执行相应的任务的过程。如下图所示:
具体各个寄存器的作用如下:
♦CS——代码段寄存器(Code Segment Register),其值为代码段的段值;
♦DS——数据段寄存器(Data Segment Register),其值为数据段的段值;
♦ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
♦SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值;
♦FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
♦GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
3.2 程序
从程序员的角度来说,程序员使用高级语言(如C)将程序写好后,通过预处理、编译、汇编、链接后,生成二进制代码,装载到计算机的内存中,便于CPU逐条执行。过程如下:
1. 编译阶段,在这个阶段中,Gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言。用户可以使用”-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
2. 汇编阶段把*.s文件翻译成二进制机器指令文件*.o,如命令gcc -c hello.s -o hello.o,其中-c告诉gcc进行汇编处理。这步生成的文件是二进制文件,直接用文本工具打开看到的将是乱码,我们需要反汇编工具如GDB的帮助才能读懂它。
3. 在成功编译之后,就进入了链接阶段。在程序中如果调用了一些系统函数库里边的函数,以printf为例,在这个阶段总,gcc将会默认到系统默认的路径中搜索这些函数,在这里会链接到libc.so.6库函数中,这样就能实现函数printf了。
梁昱森 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000