简单讨论操作系统的工作机制

来源:互联网 发布:有人使用中文域名吗 编辑:程序博客网 时间:2024/06/17 08:00
作者:黄志恒原创作品转载请注明出处http://blog.csdn.net/shazhoulada1/article/details/44063107   

《Linux内核分析》课程地址:http://mooc.study.163.com/course/USTC-1000029000

本篇文章以一段简单的C语言程序在Linux操作系统栈上的运行情况,来讨论操作系统的工作机制。
首先是这段C代码main.c
int g(int x)
{
return x+59;
}

int f(int x)
{
return g(x);
}

int main(void)
{
return f(19)+59;
}

这段代码的功能是计算出19+59+59=137。代码很简单,下面在64位Linux 操作系统(由实验楼提供,地址http://www.shiyanlou.com/courses/195)进行编译,得到它的汇编代码。Linux指令为
gcc -S -o main.s main.c -m32
执行之后会得到main.s文件。这个就是main.c在编译之后的汇编语言文件。将main.s中的以”.”开头的语句删除后,就是下面这样的汇编语句了。main.c得到的汇编语句
下面来解读这段汇编语句在程序栈中的运行情况。
首先,从main开始(因为每个C程序都是以main为入口)。
18行:pushl %ebp
解释:将ebp放入栈顶,然后栈顶+4。即压入栈。栈顶由堆栈顶 指针esp指示。ebp是堆栈基指针,也就是栈底的位置。
19行:movl %esp,%ebp
解释: 即ebp=esp,将ebp指向esp的位置。
20行:subl $4,%esp
解释:将esp的指针指向低4字节的位置。因为栈在内存中是向下增长,所以esp减4就是扩大栈的意思。
21行:movl $19,(%esp)
解释:将19这个数字存入esp指针当前的内存中。
22行:call f
解释:调用f函数。这里面的call分解为
pushl %eip
movl f, %eip
eip中存储的是即将执行的指令。eip有自动提取下一条指令的功能。
eip不能被程序员直接使用。
此时,开始执行f函数的语句。
9行:pushl %ebp
解释:栈顶指针地址减4字节,然后将ebp压入栈顶。
10行:movl %esp,%ebp
解释:ebp=esp,即ebp指向esp的位置
11行:subl $4,%esp
解释:栈顶指针地址减4字节,即栈扩大。
12行:movl 8(%ebp),%eax
解释:esp=(int32_t )(ebp+8) 即将ebp地址加上8个字节,然后从这个地址中 的内容放入eax寄存器中。eax是累加器。
13行:movl %eax,(%esp)
解释:将eax放入esp当前指向的内存中。
14行:call g
解释:调用g函数。同样分解为
pushl %eip
movl g,%eip
此时开始执行g函数。
2行—5行功能与之前相似,不在赘述。
6行:popl %ebp
解释:将ebp指向栈顶元素,然后栈顶指针地址加4字节,即栈缩小。
7行:ret
解释:ret分解为
popl %eip
即将栈顶元素存入eip,同时栈顶指针地址加4字节,栈缩小。
此时会跳转到15行。
15行:leave
解释:leave分解为
movl %ebp,%esp
popl %ebp
即esp指向ebp的地址,然后使ebp指向栈顶元素,之后再缩小栈。
16行:ret
解释:popl %eip 此时跳转到23行
23行:addl $59,%eax
解释:eax中的内容加上59
24行,25行前面已解释,不再赘述。

上面的运行解释在栈中的运行状况如下图栈运行图
对上图的解释:
1、栈是向下增长的,所以开口向下。栈上标记的0,1,2…8是表示栈的地址。
2、esp和ebp的线上的数字是esp和ebp指针指向顺序,第1次,第2次等等。
3、黑色的线表示在做压栈操作,红色的线表示正在做出栈操作。
4、eip(23)的“23”指的是代码行第23行,ebp(_0)指的是栈上地址0。

从上图可以看到,程序开始前esp和ebp都指向0,程序结束后esp和ebp也都指向0。这里的意思是说esp与ebp的起点一样。(事实上在程序开始执行前是没有为这个程序服务的栈的,程序结束后这个为其服务的栈也随之被回收掉。)所以从程序执行开辟栈,到程序结束清空栈的过程是非常清楚的。

从上述C程序在内存栈中的执行来理解操作系统的工作机制:
计算机由一个个程序组成,其中操作系统这个系统程序是其他程序运行的基石。现代计算机的结构大都是冯·诺依曼结构。这个结构的最大特点是运行的程序被存储到内存中运行。在这里,就是为这个C程序开辟栈。
操作系统为每个运行的程序开辟栈,之后这个程序运行时的数据便在栈中存储。
对于一个由高级语言编写的程序,在计算机的执行流程是:
高级语言—>汇编语言—>机器语言—>执行。
本文章只讨论程序运行时的操作系统工作机制,其他操作系统的工作机制将在后续文章中讨论。

0 0
原创粉丝点击