这种解决方式是有一个缺陷 。如下所示,假设有两个程序,每个大小各为 16 KB

文章插图
从图上可以看出,这是两个不同的 16KB 程序的装载过程,a 程序首先会跳转到地址 24,那里是一条 MOV 指令,然而 b 程序会首先跳转到地址 28,地址 28 是一条 CMP 指令 。这是两个程序被先后加载到内存中的情况,假如这两个程序被同时加载到内存中并且从 0 地址处开始执行,内存的状态就如上面 c 图所示,程序装载完成开始运行,第一个程序首先从 0 地址处开始运行,执行 JMP 24 指令,然后依次执行后面的指令(许多指令没有画出),一段时间后第一个程序执行完毕,然后开始执行第二个程序 。第二个程序的第一条指令是 28,这条指令会使程序跳转到第一个程序的 ADD 处,而不是事先设定好的跳转指令 CMP,由于这种不正确访问,可能会造成程序崩溃 。
上面两个程序的执行过程中有一个核心问题,那就是都引用了绝对物理地址,这不是我们想要看到的 。我们想要的是每一个程序都会引用一个私有的本地地址 。IBM 360 在第二个程序装载到内存中的时候会使用一种称为 静态重定位(static relocation) 的技术来修改它 。它的工作流程如下:当一个程序被加载到 16384 地址时,常数 16384 被加到每一个程序地址上(所以 JMP 28会变为JMP 16412 ) 。虽然这个机制在不出错误的情况下是可行的,但这不是一种通用的解决办法,同时会减慢装载速度 。更近一步来讲,它需要所有可执行程序中的额外信息,以指示哪些包含(可重定位)地址,哪些不包含(可重定位)地址 。毕竟,上图 b 中的 JMP 28 可以被重定向(被修改),而类似 MOV REGISTER1,28 会把数字 28 移到 REGISTER 中则不会重定向 。所以,装载器(loader)需要一定的能力来辨别地址和常数 。
一种存储器抽象:地址空间把物理内存暴露给进程会有几个主要的缺点:第一个问题是,如果用户程序可以寻址内存的每个字节,它们就可以很容易的破坏操作系统,从而使系统停止运行(除非使用 IBM 360 那种 lock-and-key 模式或者特殊的硬件进行保护) 。即使在只有一个用户进程运行的情况下,这个问题也存在 。
第二点是,这种模型想要运行多个程序是很困难的(如果只有一个 CPU 那就是顺序执行) 。在个人计算机上,一般会打开很多应用程序,比如输入法、电子邮件、浏览器,这些进程在不同时刻会有一个进程正在运行,其他应用程序可以通过鼠标来唤醒 。在系统中没有物理内存的情况下很难实现 。
地址空间的概念如果要使多个应用程序同时运行在内存中,必须要解决两个问题:保护和 重定位 。我们来看 IBM 360 是如何解决的:第一种解决方式是用保护密钥标记内存块,并将执行过程的密钥与提取的每个存储字的密钥进行比较 。这种方式只能解决第一种问题(破坏操作系统),但是不能解决多进程在内存中同时运行的问题 。
还有一种更好的方式是创造一个存储器抽象:地址空间(the address space) 。就像进程的概念创建了一种抽象的 CPU 来运行程序,地址空间也创建了一种抽象内存供程序使用 。地址空间是进程可以用来寻址内存的地址集 。每个进程都有它自己的地址空间,独立于其他进程的地址空间,但是某些进程会希望可以共享地址空间 。
基址寄存器和变址寄存器最简单的办法是使用动态重定位(dynamic relocation)技术,它就是通过一种简单的方式将每个进程的地址空间映射到物理内存的不同区域 。从 CDC 6600(世界上最早的超级计算机)到 Intel 8088(原始 IBM PC 的核心)所使用的经典办法是给每个 CPU 配置两个特殊硬件寄存器,通常叫做基址寄存器(basic register)和变址寄存器(limit register) 。当使用基址寄存器和变址寄存器时,程序会装载到内存中的连续位置并且在装载期间无需重定位 。当一个进程运行时,程序的起始物理地址装载到基址寄存器中,程序的长度则装载到变址寄存器中 。在上图 c 中,当一个程序运行时,装载到这些硬件寄存器中的基址和变址寄存器的值分别是 0 和 16384 。当第二个程序运行时,这些值分别是 16384 和 32768 。如果第三个 16 KB 的程序直接装载到第二个程序的地址之上并且运行,这时基址寄存器和变址寄存器的值会是 32768 和 16384 。那么我们可以总结下
- 基址寄存器:存储数据内存的起始位置
- 变址寄存器:存储应用程序的长度 。
推荐阅读
- 图解Java内存区域
- 分享几款Linux 下C/C++程序内存泄漏检查工具
- 建议收藏 全网最全的SQL语句
- 安卓平板|vivo发布OriginOS HD大屏操作系统:手机、平板、PC无缝协同
- 白茶萎凋,白茶萎凋适度特征
- centos操作系统上实现网卡端口绑定
- 微信太“吃”内存了!教你怎样快速清理微信垃圾,释放手机内存?
- 在常用Linux操作系统中安装VMware Tools
- 聊聊 Linux 的内存统计
- 一加|12GB内存!一加首款天玑8100新机现身GeekBench:或为一加Ace
