程序计算机中是如何运行的


操作系统03

程序在计算机中是如何运行的

#include <stdio.h>

int main(void) {
	int a=1;
	printf("%p\n",&a);
	printf("%p\n",main);	
	return 0;
}

上面的一段程序打印出来的地址是真实的物理地址吗?
答案是:
不是,所有这些打印出来的地址都是虚拟的,在物理内存中这些地址并不真实存在,
它们最终都将由操作系统和 CPU 硬件翻译成真正的物理地址,
然后才能从真实的物理位置获取该地址的值。

什么是虚拟寻址(virtual addressing)?

CPU 生成虚拟地址并进行地址翻译的流程:

  • ​ CPU 通过生成一个虚拟地址来访问主存,这个虚拟地址在被送到内存之前会先被转换成合适的物理地址,这个虚拟地址到物理地址的转换过程称为 地址翻译/地址转换(address translation)。
  • ​ CPU 上的内存管理单元(Memory Management Unit,MMU)就是专门用来进行虚拟地址到物理地址的转换的,不过 MMU 需要借助存放在内存中的查询表,而这张表的内容正是由操作系统进行管理的。

为什么引入虚拟物理寻址?

​ 真实物理寻址将全部内存信息保存的太慢,而且在进程对应的内存留在物理内存中,上下文切换时切换到特定区域,这种方式存在安全隐患,因此操作系统引入一个新的内存抽象–虚拟寻址(地址空间)

虚拟寻址的作用:
当你运行一个程序也就是一个进程时,操作系统会给这个进程分配一个虚拟地址空间,该进程的虚拟地址空间,独立于其他进程的地址空间,这样就不会发生冲突。
在程序中定义的栈、堆、代码段都是虚拟地址空间,它们的实际物理地址是不可见的,这样就保护了进程的安全性。

为什么设计分层存储体系?

分层存储体系如上图所示,每个人都希望自己的计算机容量无限大,访问速度无限快,并且能永久性的存储而且不能太昂贵,可是目前的技术水平达不到,因此人们探索出分层存储体系来将这些需求拆开对应到不同的存储器上,这样计算机就拥有:

  • 若干超级快速的寄存器,但超级昂贵,且具有易失性;
  • 若干快速的高速缓存器,但由于和CPU制作材料相同所以同样昂贵且具有易失性;
  • 速度和价格都适中,但同样易失的内存;
  • 低速廉价但具有非易失性的磁盘

程序在计算机中是如何运行的呢

当你双击火狐浏览器时,操作系统通过图形界面(GUI)知道你需要运行这个软件,它就会到磁盘中找到你安装的软件,并把运行所需要的数据复制到内存中,由CPU直接和内存进行交互,读取内存中的数据处理,并返回对应的结果保存到内存中。

Tips:软件不是在磁盘中运行的,而是在内存中运行的,因为内存的读写速度比磁盘快,为了缓和磁盘之间的速度不匹配问题,程序执行前必须将硬盘上的数据复制到内存,CPU 才能够着手处理,这个过程就是载入内存(Load into Memory)

比如说,我们打开了某个 Word 文档,并输入了一些文字,虽然我们直观看到的已经发生变化了,但是磁盘中存储的文档仍然没有改变,它仍然是之前的数据,新增的文字只是暂时保存到了内存,只有我们手动保存了这篇文档比如 Ctrl + s 才会将修改保存到磁盘中。

而由于内存是易失性的,也就是说断电后数据就丢失了,所以如果你编辑完 Word 文档忘记保存或者断电导致关机了,那么你将永远无法找回这些内容。

寄存器(Register)和高速缓存都直接内嵌在 CPU 中

常说 32 位或者 64 位的 CPU,其实指的就是寄存器的位数,寄存器功能涵括数学运算,控制程序执行流程、标记CPU运行状态等

  • EAX 寄存器通常被用在加法运算中,用来保存某个加数或运算结果;
  • EIP 寄存器中存储的值是下一条指令的地址,CPU 执行完当前指令后,就会根据 EIP 的值去寻找下一条指令,也就是说如果我们改变 EIP 寄存器的值,也就会相应的改变程序的执行流程。

高速缓存的作用:

如果 CPU 每次都从内存中读取数据,会严重拖慢其运行速度,CPU 不得不浪费大量的时间来等待内存中数据操作的结束。为此,我们在 CPU 内部设置一个缓存,将使用频繁的数据暂时从内存中读取到缓存里来,这样,如果缓存命中,就直接从缓存中读取即可,不必访问内存了。

虚拟内存

程序内存的占用不等于实际内存的大小,当程序运行所需存储空间大于内存容量时,会把内存中暂时不用的数据写回磁盘,当需要的时候重新读取,内存中存放的数据就是热点数据。这样磁盘有一部分空间存放内存暂时不用的数据,这个数据就是虚拟内存。

比如说:有时候电脑只有4g内存但是能运行需要5g内存的应用程序,这是怎么回事呢?答案是:有1g的虚例内存。对于用户来说似乎有了个比实际内存大的多的内存,但实际的物理内存大小并没有发生改变,只是在逻辑上进行了扩充。

可以这么理解,引入虚拟内存的概念后,在内存和磁盘之间,内存就充当了缓存的作用。CPU 优先从内存中获取数据,如果命中,就不需要去访问磁盘。这里和我们上文所说的 CPU 中的缓存和内存之间的关系是不是一模一样?

本文参考来源:


文章作者: 冰冰的小屋
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 冰冰的小屋 !
  目录