内存的基础知识 - 图1

内存是什么?有什么作用?

内存是用于存放数据的硬件。程序执行前需要先放到内存中才能被 CPU 处理。(缓和 CPU 与硬件之间的速度矛盾)

在多道程序环境下,系统中会有多个程序并发执行,也就是说会有多个程序的数据需要同时放到内存中。那么,如何区分各个程序的数据是放在什么地方的呢?

问题:如何区分各个程序的数据存放的位置

  • 内存中也有一个一个的小房间,每个小房间就是一个 存储单元
  • 给内存的存储单元 编号
  • 如果计算机 按字节编号,则 每个存储单元大小1 字节,即 8B,即 8 个二进制位
  • 如果 字长为 16 位的计算机 按字编址,则 每个存储单元大小 1 个字,即每个字大小为 16 个二进制位

常用的数量单位

一台手机/电脑有 4GB 内存,是什么意思?
是指该内存中可以存放 42^30 各子节。如果是按字节编址的话,也就是有 420^30=2^32 个小房间。

2^10 = 1K(千)
2^20 = 1M(兆,百万)
2^30 = 1G(十亿,千兆)

指令的工作原理

对于一个写好的程序,经过编译、链接,会形成可执行文件。

可执行文件中的内容是一个个的指令(二进制),指令中的地址都是相对地址(相对于该可执行文件的地址,又称逻辑地址)。

每次真正运行的时候,需要把可执行文件装入内存中,内存会开辟一段空间专门给这个程序。

这样就会涉及到两个问题:

  1. 逻辑地址和物理地址的转换
  2. 装入方式


装入方式

绝对装入

在编译时,如果知道程序将放在内存的位置,编译程序就直接产生绝对地址的目标代码。

缺点:如果分配的内存地址发生改变,需要重新编译链接生成新的目标代码,灵活性不高

可重定位装入(静态重定位)

编译链接生成目标代码的时候,依然生成相对地址,当装入内存的时候,把所有地址都加上起始物理地址。

缺点:在装入一个作业时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能够装入该作业。作业一旦装入内存,在运行期间也不可以移动,也不可以申请新的内存空间

动态运行时装入(动态重定位)

装入内存的时候,依然采用相对地址,把地址转换工作推迟到程序真正要执行时才进行。需要借用一个重定位寄存器的支持。

重定位寄存器中保存装入模块存放的 起始位置。

特点:

  • 可将程序分配到 不连续 的内存空间中
  • 运行某一部分代码时,装入相应的代码即可
  • 便于用户共享程序段

采用动态重定位时 允许程序在内存中发生移动。

并且可将程序分配到不连续的存储区中;在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

链接方式

静态链接

image.png

在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(转入模块),之后不再拆开

装入时动态链接(静态重定位)

image.png

将各目标模块装入内存时,边装入边链接的方式

运行时动态链接(动态重定位)

image.png

在执行程序中需要用到的目标模块才对它进行链接。优点:方便修改和更新,便于对目标模块的共享。