内存(Memory)是计算机系统中用于存储程序、数据和操作系统的重要组件之一。它是计算机中的一种主要存储设备,用于临时存储数据和指令,供CPU进行读写操作。
作用:
内存用于存储正在运行的程序、操作系统和数据。它是CPU能够直接访问的存储设备,能够提供非常快速的读写速度,因此被广泛用于存储正在执行的程序和数据。
组成:
内存由一组存储单元组成,每个存储单元通常由一个或多个存储元件组成,用于存储一个位或多个位的数据。
存储单元通常以二进制编码来表示数据,即0和1。每个存储单元都有一个唯一的地址,CPU可以通过地址来读取或写入存储单元中的数据。
计算机内存中包含了地址线、控制线和数据线,它们协同工作以实现对内存的访问和操作。
①地址线
:地址线是用于传输内存地址信息的信号线;它们将CPU发送的内存地址传递给内存模块,用于选择内存中的特定存储单元。地址线的数量决定了取值范围,例如一个系统有 n 条地址线,则它可以寻址的内存地址数量为 2^n 个。
②控制线
:控制线是用于控制内存读写操作的信号线;控制线向内存模块发送读写命令以控制数据的读写操作,控制数据的传输和存储。
③数据线
:数据线是用于传输数据的信号线。它们将CPU发送的数据传递给内存模块,或者将内存模块中的数据传递给CPU;数据线的数量决定了内存模块每次可以传输的数据位数,例如一个系统有 m 条数据线,则每次可以传输 m 位的数据。
当CPU需要读取或写入内存时,它将发送地址信号到内存模块,控制内存模块执行读写操作,并通过数据线传输数据。
内存字节序
内存的字节序(endianness)指的是多字节数据在内存中存储时的字节顺序。有两种主要的字节序:大端序(Big Endian)和小端序(Little Endian)。
大端序(Big Endian)
在大端序中,多字节数据的高字节存储在内存的低地址处,低字节存储在内存的高地址处。换句话说,数值的最高有效字节(Most Significant Byte, MSB)存储在内存的起始地址。举例说明,如果我们有一个32位的整数 0x12345678
,它在内存中的存储方式如下:
地址 值
0x00 0x12
0x01 0x34
0x02 0x56
0x03 0x78
小端序(Little Endian)
在小端序中,多字节数据的低字节存储在内存的低地址处,高字节存储在内存的高地址处。换句话说,数值的最低有效字节(Least Significant Byte, LSB)存储在内存的起始地址。
举例说明,同样的32位整数 0x12345678
在内存中的存储方式如下:
地址 值
0x00 0x78
0x01 0x56
0x02 0x34
0x03 0x12
在计算机中,高字节(high byte)和低字节(low byte)是指一个多字节数据(如16位、32位、64位等)中的不同部分。
高字节和低字节的定义
低字节(Low Byte):数据的最低有效部分,即最低的8位。
高字节(High Byte):数据的最高有效部分,即最高的8位。
假设我们有一个16位(2字节)的整数:
uint16_t value = 0x1234;
在这个16位整数中:
0x12
是高字节0x34
是低字节
实际应用
处理器架构:不同的处理器架构可能采用不同的字节序。比如,x86架构使用小端序,而一些RISC处理器,如PowerPC,则使用大端序。
网络协议:互联网协议(如TCP/IP)规定数据在网络上传输时使用大端序,这被称为“网络字节序”。
文件格式:某些文件格式规定了字节序,比如BMP图像文件使用小端序,而PNG图像文件则使用大端序。
内存的段概念
段(Segment)是计算机内存管理中的一种概念,用于分割和组织内存空间。在不同的计算机体系结构和操作系统中,段的使用方式可能有所不同,但总体上,段的概念用于帮助管理内存、提高内存使用效率和实现内存保护。
段的基本概念
段(Segment)
段是内存中的一个逻辑区域,可以包含代码、数据或堆栈。每个段都有一个起始地址和一个长度。段可以分为以下几种类型:
代码段(Code Segment):存储程序的可执行代码。 数据段(Data Segment):存储程序的全局变量和静态数据。 堆栈段(Stack Segment):存储函数调用的堆栈,包括局部变量和返回地址。 额外段(Extra Segment):在某些体系结构中,用于存储额外的数据,比如字符串操作中的数据。
分段内存管理
在分段内存管理中,内存被划分为多个段,每个段独立地进行管理。每个段可以具有不同的大小,并且可以独立地增长和收缩。这种方法有助于实现内存保护和共享。
段寄存器用于存储段选择器或段基地址,这些段选择器或基地址与偏移量组合在一起形成有效的内存地址。那么现在有一个问题:CS段(寄存器)只有16位,8086有20根地址线,此时地址和如何存储?
实模式
在实模式下,x86处理器使用一种简单的内存寻址方式。16位的段寄存器和16位的偏移量结合起来形成一个20位的物理地址。具体计算方式如下:
物理地址 = 段基地址 × 16 + 偏移量
16位段寄存器示例
假设段寄存器CS的值是 0x1234
,而指令指针(IP)的值是 0x5678
,那么计算物理地址的方法如下:
段基地址 = 0x1234 × 16 = 0x12340
偏移量 = 0x5678
物理地址 = 0x12340 + 0x5678 = 0x179B8
保护模式下的段寄存器
在保护模式(Protected Mode)下,段寄存器存储段选择器而不是直接的段基地址。
段选择器(Segment Selector)
段选择器是用来标识一个段的特殊值。在x86架构中,段选择器存储在段寄存器(如CS、DS、SS、ES、FS、GS)中,每个段选择器对应一个段描述符,描述符包含段的起始地址、长度和访问权限等信息。
15 3 2 1 0
+---------+--+--+--+
| Index |TI|RPL|
+---------+--+--+--+
段描述符(Segment Descriptor)
段描述符是存储在段描述符表(GDT或LDT)中的结构,用于描述段的属性。一个段描述符通常包含以下信息:
段的基地址
段的长度
段的类型和权限(如读/写权限、执行权限)
段的状态(如存在位)
地址转换过程
段选择器加载:加载段寄存器时,段选择器指向段描述符表中的段描述符。
段描述符查找:根据段选择器中的索引,从GDT或LDT中获取段描述符。
基地址和限长:段描述符包含段的基地址和限长。
线性地址计算:段基地址与偏移量相加,形成线性地址。
分页机制(如果启用):线性地址经过分页机制转换为物理地址。