SA*****160 吴*
实验要求:
1.使用Example的C代码分别生成.cpp,.s,.o和ELF可执行文件,并加载运行,分析.s汇编代码在CPU上的执行过程
2.通过实验解释单任务计算机是怎样工作的,并在此基础上讨论分析多任务计算机是怎样工作的
实验环境:
1.操作系统:VMware+Ubuntu 12.04 LTS(32-bit)
2.硬件平台:32位X86
Example的C代码如下:
#include <stdio.h> int g(int x) { return x + 3; } int f(int x) { return g(x); } int main(void) { return f(8) + 1; }
实验过程:
1.逐步生成可执行文件(gcc的编译过程)
1.1预处理
gcc -E -o example.cpp example.c
生成了.cpp文件
wc example.c example.cpp
使用wc命令比较预处理后的文件与源文件,可以看到两个文件的差异
1.2编译成汇编代码
gcc -x cpp-output -S -o example.s example.cpp
生成.s文件
1.3汇编成目标代码
gcc -x assembler -c example.s
生成.o文件
1.4链接
gcc -o example example.o
生成elf可执行文件example
2.分析example.s汇编代码在CPU上的执行过程
2.1反汇编
objdump -d example >a.s
将可执行文件example反汇编成汇编代码,存储在a.s文件中,如下图所示:
080483b4 <g>: 80483b4: 55 push %ebp 80483b5: 89 e5 mov %esp,%ebp 80483b7: 8b 45 08 mov 0x8(%ebp),%eax 80483ba: 83 c0 03 add $0x3,%eax 80483bd: 5d pop %ebp 80483be: c3 ret 080483bf <f>: 80483bf: 55 push %ebp 80483c0: 89 e5 mov %esp,%ebp 80483c2: 83 ec 04 sub $0x4,%esp 80483c5: 8b 45 08 mov 0x8(%ebp),%eax 80483c8: 89 04 24 mov %eax,(%esp) 80483cb: e8 e4 ff ff ff call 80483b4 <g> 80483d0: c9 leave 80483d1: c3 ret 080483d2 <main>: 80483d2: 55 push %ebp 80483d3: 89 e5 mov %esp,%ebp 80483d5: 83 ec 04 sub $0x4,%esp 80483d8: c7 04 24 08 00 00 00 movl $0x8,(%esp) 80483df: e8 db ff ff ff call 80483bf <f> 80483e4: 83 c0 01 add $0x1,%eax 80483e7: c9 leave 80483e8: c3 ret 80483e9: 90 nop 80483ea: 90 nop 80483eb: 90 nop 80483ec: 90 nop 80483ed: 90 nop 80483ee: 90 nop 80483ef: 90 nop
2.2栈的分析
2.2.1
2.2.2
2.2.3
2.2.4
2.2.5
2.2.6
2.2.7
2.2.8
2.2.9
2.2.10
2.2.11
实验总结:
1.单任务计算机是怎样工作的
单任务计算机中CPU串行执行程序,直到此程序执行结束才会执行其它程序。CPU寄存器中eip寄存器总指向下一条将要执行的指令。
2.多任务计算机是怎样工作的
多任务计算机将CPU的时间分成时间片,每个程序一次只能执行一个时间片,时间片耗尽后操作系统就会将CPU资源分给其它程序。这之间的切换程序的操作需要中断的支持。大致流程如下:首先程序A在运行,如果它的时间片用完了,计算机会产生一个中断;然后保护现场,给eip寄存器赋值,使其指向接下来要执行的程序B;最后如果又轮到程序A的时候,系统产生中断之后,操作系统要保护当前程序的现场,恢复将要执行的程序A的现场,使其重新占用CPU,正常运行。
疑问:
80483d5: 83 ec 04 sub $0x4,%esp
80483d8: c7 04 24 08 00 00 00 movl $0x8,(%esp)
为什么不直接push?