Linux内核分析之计算机是如何工作的
一、计算机工作原理
本周实验主要是反汇编C代码,生成汇编程序。冯·诺依曼理论的要点是:数字计算机的数制采用二进制,计算机应该按照程序顺序执行。人们把冯·诺依曼的这个理论称为冯·诺依曼体系结构。CPU通过总线从内存中读取一条条程序,根据程序的内容执行具体的步骤。CPU在读取指令时,通过寄存器IP来指向下一条指令(如果是32位系统,则为EIP),CPU的寄存器分为通用寄存器、段寄存器、状态寄存器。可以用一张图来说明
进程是一个可执行程序的实例。从内核角度看,进程由用户内存空间和一系列内核数据结构组成,其中用户内存空间包含了程序代码及代码使用的变量,而内核数据结构用于维护进程状态信息。每个进程分配的内存由很多部分组成。当计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,在控制器的指挥下完成规定操作。依此进行下去。直至遇到停止指令。
计算机的寻址方式老师介绍了以下几种:
movl %eax,%edx edx=eax 寄存器寻址
movl $0x123,%edx edx=0x123 立即寻址
movl 0x123,%edx edx=*(int32_t*)0x123 直接寻址
movl (%ebx),%edx edx=*(int32_t*)ebx 间接寻址
movl 4(%ebx),%edx edx=*(int32_t*)(ebx+4) 变址寻址
二、实验内容
对于简单C语言程序main.c
int g(int x)
{
return x + 4;
}
int f(int x)
{
return g(x);
} int main(void)
{
return f(5) + 1;
}
使用如下命令编译成汇编代码,然后删除汇编代码中用于链接的辅助信息:
gcc –S –o main.s main.c -m32
得到的文件保存在main.s中
g:
pushl %ebp
movl %esp, %ebp
movl (%ebp), %eax
addl $4, %eax
popl %ebp
ret f:
pushl %ebp
movl %esp, %ebp
subl $, %esp
movl (%ebp), %eax
movl %eax, (%esp)
call add
leave
ret main:
pushl %ebp
movl %esp, %ebp
subl $, %esp
movl $5, (%esp)
call f
addl $1, %eax
leave
ret
处理后的汇编代码为:
设空栈如下:
从main开始执行,以下为逐句解释:
最开始的时候ebp和esp都指向标号0的位置
pushl %ebp :ebp入栈,保存当前ebp0,esp-4指向标号1
movl %esp, %ebp :将ebp指向标号1
subl $, %esp :esp-,指向标号2
movl $5, (%esp) :esp指向的栈中标号2对应的地方存储5
call sec :将eip()入栈,esp-4指向标号3,跳转至f执行
接下来执行f中的代码:
pushl %ebp :将ebp()入栈,esp-4指向标号4
movl %esp, %ebp :ebp指向标号4
subl $, %esp :esp-,指向标号5
movl (%ebp), %eax :将ebp指向的地址加八对应地址中的数据放入eax,即标号2对应存储数据5,所以(eax)=5
movl %eax, (%esp) :把eax放入esp对应位置,即栈中标号5对应位置
call g :将eip()入栈,esp-4指向标号6,跳转至g执行
接下来执行g中的代码:
pushl %ebp :ebp()入栈,esp-4指向标号7
movl %esp, %ebp :ebp指向标号7
movl (%ebp), %eax :ebp+8位置中的数据赋给eax,即标号5位置,(eax)=5
addl $4, %eax :eax中数据+4,即5+4=9
popl %ebp :ebp()出栈,即ebp指向标号4,esp+4指向标号6
ret :eip()出栈,esp+4指向标号5,跳转至第16行继续执行
接下来又回到f中继续执行:
leave :把ebp赋给esp,即esp指向标号4,ebp()出栈,esp+4指向标号3,ebp指向标号1
ret :eip()出栈,esp+4指向标号2,跳转至第25行继续执行
接下来回到main中继续执行:
addl $1, %eax :eax中的数据+1,即9+1=10
leave :把ebp赋给esp,即esp指向标号1,ebp()出栈,ebp指向标号0,esp+4指向标号0
ret :此时栈已经空了,恢复最开始的状态,运行结束,最后的结果保存在eax中,为10。
三、 堆栈变化分析
程序从main.s第17行开始运行,CPU的IP寄存器指向汇编代码的第18行,假设堆栈在内存中的地址分别为0,1,2,3……堆栈基指针寄存器(EBP)和堆栈顶指针寄存器(ESP)均指向堆栈段0处。第18~21行首先为main函数开辟新的内存区域,之后将传的参数5入栈,此时堆栈段如下所示:
然后程序调用call 函数,将IP入栈,IP指向代码第9行f处。
在f函数的代码处,首先为f函数开辟新的内存区域,接着将传入的参数5赋值给EAX,并将EAX入栈
程序在此调用call进入g函数。在g函数中,同样先是开辟内存空间,然后将参数传给EAX,并将EAX的值加上4。之后将EBP出栈,并调用ret命令。此时IP重新指向f函数call之后的命令。
之后就是不断的调用leave与ret命令,跳出当前的内存区域,回到上一级函数的内存区域中
ret指令执行后函数g调用完毕,返回。leave指令用于释放一个子例程的栈帧,等价与以下两条指令:
- movl %ebp, %esp
- popl %ebp
并将EAX的值加4,直到跳出main函数,至此程序结束
四、总结
通过本次课程的学习,我掌握了存储计算机工作模型和汇编的基础知识。计算机的基本原理是存贮程序和程序控制。预先要把指挥计算机如何进行操作的指令序列(称为程序)和原始数据通过输入设备输送到计算机内存贮器中。每一条指令中明确规定了计算机从哪个地址取数,进行什么操作,然后送到什么地址去等步骤。
其中,掌握冯·诺依曼体系结构是理解计算机工作原理的要点。按照冯·诺依曼存储程序的原理,计算机在执行程序时须先将要执行的相关程序和数据放入内存储器中,在执行程序时CPU根据当前程序指针寄存器的内容取出指令并执行指令,然后再取出下一条指令并执行,如此循环下去直到程序结束指令时才停止执行。其工作过程就是不断地取指令和执行指令的过程,最后将计算的结果放入指令指定的存储器地址中。
在课程中提到了很多操作系统的内容由于知识结构,我比较欠缺,今后我会加强这方面的知识储备。
刘帅
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
Linux内核分析之计算机是如何工作的的更多相关文章
- Linux内核分析之操作系统是如何工作的
在本周的课程中,孟老师主要讲解了操作系统是如何工作的,我根据自己的理解写了这篇博客,请各位小伙伴多多指正. 一.知识点总结 1. 三个法宝 存储程序计算机:所有计算机基础性的逻辑框架. 堆栈:高级语言 ...
- linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作
一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...
- 《Linux内核分析》第一周 计算机是如何工作的?
刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK ONE(2. ...
- LInux内核分析——计算机是如何工作的进行
万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 " 实 ...
- Linux内核分析第一周学习总结:计算机是如何工作的?
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.冯诺依曼体系 ...
- 《Linux内核分析》第一周笔记 计算机是如何工作的
一.计算机是如何工作的? 1.存储程序计算机工作模型 1)冯诺依曼体系结构 学习研究计算机的基本概念.就是指存储程序计算机.所有的有计算功能的电子设备小到计算器,大到超级计算机核心部分都可以用这种体系 ...
- 《Linux内核分析》第一周学习小结 计算机是如何工作的?
<Linux内核分析>第一周.计算机是如何工作的? 20135204 郝智宇 一.存储程序计算机工作模型 1. 冯诺依曼体系结构: 数字计算机的数制采用二进制:计算机应该按照程 ...
- 《Linux内核分析》 之 计算机是如何工作的
[李行之原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] <Linux内 ...
- linux内核分析--计算机是如何工作的
实验部分 使用gcc -S -o main.s main.c -m32命令将源代码编译成汇编代码. 源代码如下: int g(int x) { return x + 9; } int f(int x) ...
随机推荐
- 三、Distributing Maya Plugins
For example, a fully implemented render utility node will have at least three files: the plug-in fil ...
- yum install mysql
rpm -qa|grep -i mysqlmysql-libs-5.1.52-1.1.alios6.1.x86_64mysql-5.1.52-1.1.alios6.1.x86_64mysql-deve ...
- location.href跳转不正确
今天写这个随笔的用意是为了记录我遇到的一种情况,导致我页面无法正确跳转 location.href跳转页面其实很简单,只要附上url就可以了,但是今天我在测试一个跳转时是这么写的: location. ...
- 百度地图API示例之设置级别setZoom与禁止拖拽disableDragging
百度地图API示例之设置级别setZoom与禁止拖拽disableDragging 设置级别 <html> <head> <meta http-equiv="C ...
- NHibernate系列文章七:NHibernate对象状态
摘要 NHibernate对象持久化 NHibernate对象的三个状态:临时态.持久态.游离态(托管态) NHibernate三状态的相互转化 1. NHibernate对象持久化 NHiberna ...
- 【EF学习笔记05】----------操作内存中的数据
SingleOrDefault实验 //SingleOrDefault实验 using (var db = new Entities()) { var classes = new Classes() ...
- myeclipse 在mac中字体模糊问题解决方案
找到文件:/Applications/MyEclipse 2014/MyEclipse 2014.app/Contents/Profile/myeclipse.app/Contents/Info.pl ...
- IMoniker接口的成员
- H5测试区别与PC端测试关注点
除了基本的业务逻辑功能测试之后,H5页面的测试,需要关注以下几点: 1. 通过H5网页(非手机的返回功能)的返回功能可以返回,不会出现无法返回的情况. 2. 横屏竖屏相互切换,能自适应,并且布局不 ...
- sed命令手册
sed 是一种在线编辑器,它一次处理一行内容. 处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space). 接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内 ...