进程的内存映射

在现代 OS 中,多个程序(进程)同时运行,即物理层面上单一的存储器必须被多个进程共同使用。
这时如果根据进程来区分可用的地址,那么程序的编写就会变得非常麻烦。因为这样程序的整体就无法使用绝对地址,无法使用绝对地址就不得不逐一根据相对位置来计算地址,非常麻烦,并且速度低下。
在可以同时运行多道进程的现代计算机中,在 CPU 和 OS 的协作下,所有的进程看上去都可以使用从 0 地址开始的独立的存储器地址。也就是说,虽然从 0 地址开始的存储器实际上只有一个,但各个进程看上去可以独占这片存储器。
首先,将物理存储器分割为页(page)。接着,当进程需要内存时,OS 会将新的页分配给进程,并将此页的虚拟地址和物理地址的对应关系记录到 OS 管理的“地址转换表”中。之后就是 CPU 的工作了。进程使用虚拟地址访问存储器时,CPU 内部称为 MMU(Memory Management Unit)的设备会访问地址转换表进行地址转换

C 语言的指针就是保存虚拟地址的数据类型。例如将整数 15000 强制转换为 char* 类型并访问,就能够得到该进程的地址空间中 15000 地址上的值

“×× 位CPU”的定义比较模糊,但至少要满足下面这 2 个条件才能真正地被称为“n 位 CPU”。

  1. 具备 n 位宽的通用寄存器
  2. 具备 n 位以上的地址空间

栈是一种先进后出的数据结构。IA-32 中各进程地址空间的一部分被作为栈使用,主要用于保存函数的临时变量和参数。这个特殊的栈通常也只是被称为“栈”,为了避免混淆,本书中决定将其称为机器栈。
机器栈的位置因 OS 而异。在 IA-32 的 Linux 平台上,机器栈位于各进程的地址空间中靠近 3 GB 之处,向 0 地址方向延伸。即机器栈是从靠后的地址向前进行延伸。
机器栈并不是连续的一整块。C 语言程序是通过连续的函数调用来执行的,因此机器栈也是根据每一个函数分开进行管理的。这时我们将管理 C 语言中单个函数数据的机器栈的领域称为栈帧(stack frame)。

临时变量
源函数执行中的代码地址(返回地址)
函数的参数

在每个栈帧上存储上述信息的具体步骤是由函数的调用约定(calling convention)决定的。各个 CPU 架构、操作系统的函数调用约定各不相同。

对齐(alignment)是指将数据存放在内存上时,必须放置在特定数值的倍数的地址上。“在 n 字节的倍数的地址上存放数据”还可以表述为“以 n 字节为边界排列”。
最近设计的 CPU 中有着所有的数据都必须放置在该数据大小的倍数的地址上这样的限制。
否则就会发生总线错误(bus error),导致程序异常终止。

简单的 C 语言表述的背后有着各种各样复杂的限制和规则。代替程序员应对这样
的限制也是编译器重要的职责之一。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值