在计算机中,内存地址是特定内存位置的引用,软件与硬件在各个级别上使用的内存位置。
内存地址是固定长度的数字序列,在传统上作为正整数显示与操纵。
这种数字语义本身基于处理器的功能(例如指令指针和增量地址寄存器),以及基于像各种编程语言所认可的数组之类的存储器的使用。
内存地址的类型:物理地址 vs 逻辑地址
物理地址
物理内存由许多内存位置组成,每个内存位置都有对应的 物理地址(它是代码)。处理器使用该代码访问对应的内存位置。
通常只有 系统软件(BIOS、OS)或 特定程序(Memory Tester)才会使用 机器码操作数 或 处理器寄存器 来寻址内存,以指示 处理器 指挥 硬件设备(内存控制器)来使用 内存总线或系统总线,或者分开的控制总线、地址总线、数据总线,以执行程序代码。
内存控制器的总线由许多并行线组成,每个用二进制数字(位)表示。总线的宽度、可寻址存储单元的数量、每个单元中的位数,在计算机之间会有所不同。
逻辑地址
计算机程序使用内存地址执行机器代码,并存储和检索数据。在早期计算机中,逻辑地址与物理地址是对应的。
自从虚拟内存引入以来,应用程序不再知道物理地址,而是寻址逻辑地址或虚拟地址,使用计算机的内存管理单元(MMU)和操作系统内存映射。
地址解析的单位
从内存中读取数据时,并非以 位 为单位。
最现代的计算机是 字节寻址(byte-addressable),每个地址都标识单个字节(8 bit)。大于单个字节的数据则按 连续地址 的顺序存储。
当然也有计算机是 字寻址(word-addressable),最小的寻址单元是恰好是处理器的字长(即寄存器位数)。比如 TMS9900、IMP-16 使用 16-bit 的字;比如 PDP-10 使用 18-bit 的字寻址(而非字节寻址),地址空间达到 218 个 36-bit 字,大约 1M 左右存储。
内存寻址的效率 取决于 用于寻址的总线的位大小 —— 使用的位越多,计算机可用的内存地址越多。例如 具有 20-bit 地址总线的 8-bit 字节寻址的计算机,可以寻址 220 内存位置(约有 1M 左右),而 32-bit 总线可寻址 232 位置(具有 4GB 地址)
某些较旧的计算机(十进制计算机)是可十进制数字寻址的。例如在 IBM 1620 的磁芯存储器中,每个地址都标识了一个六位二进制编码的十进制数字,由奇偶校验位、标志位、四个数字位组成。IBM 1620 使用 5 位十进制地址,因此在理论上最高的地址为 99999。而实际上,处理器支持 20000 个存储单元,最多可以添加两个可选的外部存储单元,每个单元支持 20000 个地址,总计60000(00000-59999)。
字大小 vs 地址大小
字长是计算机体系结构的特征,它表示处理器单次可处理的位数。包括嵌入式系统在内的现代处理器使用 8、16、24、32、64 位的字长;最新的通用计算机则使用 32、64 位字长。在历史上还还出现过其他字长,比如 8、9、10、12、18、24、36、39、40、48、60 位。
常常,当我们说现代计算机的字长时,也是在说计算机的地址空间。比如,当说 32-bit 计算机时,也是在说 32-bit 内存地址;字节寻址的 32-bit 计算机可以寻址 232 字节内存。这样可以高效存储内存地址。
字节寻址的 32-bit 计算机可以寻址 232 字节内存 —— 字节寻址,以字节为单位,每个内存地址对应单个字节;32-bit,处理器单次可处理的数据长度;同时,32-bit 还指内存地址空间。
但是计算机的内存地址可以大于或小于字大小(为了使用更多内存,通常大于)。例如:MOS Technology 6502 是 8-bit 处理器,但是支持 16-bit 内存地址,否则最多 28 字节;Intel 8088 与 Intel 8086 通过段(segmentation)支持 20-bit 寻址,允许访问 1MiB 而不是 64KiB 内存;自从 Pentium Pro 开始,所有 Intel Pentium 处理器包含 PAE 以支持映射 36-bit 物理地址到 32-bit 虚拟地址。许多早期的处理器每个字拥有两个地址,例如 36-bit 处理器。
在理论上,现代字节寻址的 64-bit 计算机可以寻址 264 字节,但是在实践中内存总量受限于处理器、内存控制器、印刷电路板的设计(比如物理内存连接器的数量、焊接内存的数量等等)
每个内存地址的内容
在存储程序计算机中,每个内存位置都包含某种二进制数或十进制数。在解释时,作为某些数据类型的数据或者单条指令,使用方式取决于检索和操作它的指令。
某些早期的程序员将指令与数据结合以节省内存,因为内存昂贵。
在应用程序编程中的地址空间
在现代多任务环境中,应用进程(在自己地址空间中)具有以下类型的内存块:
地址空间的某些部分可能还没有映射。
寻址方案
在计算机程序中,可以访问明确给出的地址:在低级编程中被称为绝对地址,有是也称为具体地址;在高级语言中被称为指针。
但是程序也可以使用相对地址(相对与某个地址来指定地址),还有更多间接寻址模式。
将逻辑地址映射的物理与虚拟内存还增加多个间接层。
内存模型
许多程序员喜欢寻址内存,这样代码空间与数据空间将无区别,物理内存与虚拟内存也是如此。换句话说,在数字上相同的指针指向完全相同的内存字节。
但是早期的计算机不支持如此扁平的内存模型:特别是,哈佛架构机器迫使程序存储与数据存储完全分开;许多现代数字信号处理器具有三个分离的存储区域(程序存储、协助存储、数据存储),某些常用指令会同时从这三个区域获取 —— 较少的存储区域会使这些指令执行缓慢。
在 x86 中的内存模型
早期的 x86 计算机使用基于两个数字组合的分段内存模型地址:内存段 + 偏移量。
某些段被隐式地视为代码段,专用于指令、栈段、普通数据段。尽管用法不同,但是这些段没有不同的内存保护反映出这点。
在扁平内存模型中,所有段通常被设为零,并且只有偏移可用。
参考文献