# 1. 内存的基础知识

## 1. 内存是什么 & 作用

内存**可存放数据**。程序执行之前，需要先放到内存中才能被 CPU 处理（**缓和 CPU 与硬盘之间的速度矛盾**）

**问题：**&#x5982;何区分各个程序的数据存放的位置

* 给内存的存储单元**编号**
* 如果计算机 **按字节编号**，则 **每个存储单元大小** 为 **1 字节**，即 8B，即 8 个二进制位
* 如果 字长为 16 位的计算机 **按字编址**，则 **每个存储单元大小** 为 **1 个字**，即每个字大小为 16 个二进制位

## 2. 指令的工作原理

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

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

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

这样就会涉及到**两个问题：**

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

## 3. 装入方式

### 3.1 绝对装入

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

**缺点：**&#x5982;果分配的内存地址发生改变，需要重新编译链接生成新的目标代码，灵活性不高

### 3.2 可重定位装入（静态重定位）

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

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

### 3.3 动态运行时装入（动态重定位）

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

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

**特点：**

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

## 4. 链接方式

### 4.1 静态链接

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MFKTWf15c1bFysqE-Bd%2F-MFKTm0R_YalDtkACvTX%2Fimage.png?alt=media\&token=11236c25-7f67-4b27-a4f3-c8c538c75dac)

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

### 4.2 装入时动态链接

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MFKU5Vs__YFy4fcZeGA%2F-MFKUC1Qd37LoKRP8O6Z%2Fimage.png?alt=media\&token=6c9773bf-e933-4f1d-b886-c53b0cf3a5bd)

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

### 4.3 运行时动态链接

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MFKU5Vs__YFy4fcZeGA%2F-MFKUTQbxyzpumJa__RC%2Fimage.png?alt=media\&token=4f02d304-9aa0-4bf8-98a5-b540e369cda3)

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