实验一:计算机是怎么样工作的
学号:SA***424 姓名:**明
实验环境:Virtual Box,ubuntu10.10
实验报告要求:通过实验解释单任务计算机是怎样工作的,并在此基础上讨论分析多任务计算机是怎样工作的。
Example.c
int g(int x)
{
return x+3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8)+1;
}
1.首先建立Examplle.c文件:
2.将源代码编译为二进制文件又需要经过以下四个步骤:预处理(cpp)-> 编译(gcc或g++)->汇编(as)->链接(ld)
1)经过预处理生成.cpp文件
2)编译器编译生成汇编文件
3)汇编器编译生成目标文件
4)链接后生成二进制文件elf格式
查看该二进制文件:
3.分析汇编码的执行过程
反汇编指令:objdump -d Example
08048394 <g>:
8048394: 55 push %ebp
8048395: 89 e5 mov %esp,%ebp
8048397: 8b 45 08 mov 0x8(%ebp),%eax
804839a: 83 c0 03 add $0x3,%eax
804839d: 5d pop %ebp
804839e: c3 ret
0804839f <f>:
804839f: 55 push %ebp
80483a0: 89 e5 mov %esp,%ebp
80483a2: 83 ec 04 sub $0x4,%esp
80483a5: 8b 45 08 mov 0x8(%ebp),%eax
80483a8: 89 04 24 mov %eax,(%esp)
80483ab: e8 e4 ff ff ff call 8048394 <g>
80483b0: c9 leave
80483b1: c3 ret
080483b2 <main>:
80483b2: 55 push %ebp
80483b3: 89 e5 mov %esp,%ebp
80483b5: 83 ec 04 sub $0x4,%esp
80483b8: c7 04 24 08 00 00 00 movl $0x8,(%esp)
80483bf: e8 db ff ff ff call 804839f <f>
80483c4: 83 c0 01 add $0x1,%eax
80483c7: c9 leave
80483c8: c3 ret
80483c9: 90 nop
80483ca: 90 nop
80483cb: 90 nop
80483cc: 90 nop
80483cd: 90 nop
80483ce: 90 nop
80483cf: 90 nop
首先分析一个程序的执行过程都是从mian()函数开始开始:
先看main()函数汇编指令的前五条:
此时call 804938f <f>,程序将跳到函数f去执行
此时call 8048394 <g>,eip2已经入栈,程序跳到函数g出执行
g函数返回值11给%eax,然后开始执行pop %ebp 和 ret直至g函数的栈销毁,执行示意图如下
注意此时80483b0处为leave 指令,翻译过来为 mov %ebp %esp,pop %ebp。在执行ret又返回到第一次eip1保存的地址处执行,此时堆栈为
此时eax=11+1=12,最后两条指令leave 和ret
整数函数执行完后栈为空
4.实验总结
从上述程序的实行过程中可以看出,主函数调用函数f,函数f调用函数g,每个函数都在自己的堆栈上执行,而一个程序在调用其他函数时又能正确地在执行完其他程序后返回继续执行自身函数,直到所有函数执行完毕,各自的堆栈销毁。这样就有单个任务的执行引入到了多任务机制,多任务机制必然不可避免引入了中断的概念(上面主函数执行一半后最后又返回,如同我们的中断机制)。
单任务计算机工作原理:即不考虑中断,任务顺序执行,知道该任务执行完毕后才去执行其他任务,如同串行执行。
多任务计算机工作原理:多任务计算机将CPU的时间分成时间片,每个程序一次只能执行一个时间片,时间片耗尽后操作系统就会将CPU资源分给其它程序。这之间的切换程序的操作需要中断的支持。大致流程如下:首先程序A在运行,如果它的时间片用完了,计算机会产生一个中断;然后保护现场,给eip寄存器赋值,使其指向接下来要执行的程序B;最后如果又轮到程序A的时候,系统产生中断之后,操作系统要保护当前程序的现场,恢复将要执行的程序A的现场,使其重新占用CPU,正常运行。如同上述main,f,g的执行过程,调用时保存自己的数据到堆栈,执行完后返回。