Memory management 为什么分段从段落边界开始?

Memory management 为什么分段从段落边界开始?,memory-management,assembly,x86,Memory Management,Assembly,X86,在实模式分段记忆模型中,分段总是从段落边界开始。段落的大小为16字节,因此段地址总是可以被16整除。段落边界上有段的原因/好处是什么?8086有20个地址行。段被映射到前16位,留下底部4行或16个地址的偏移量。这与其说是一个公理,不如说是一个公理-8086的实模式分段模型是在硬件级别设计的,因此段寄存器指定了段边界 段寄存器指定8086的20位地址空间的上16位的基址,该基址的下4位本质上被强制为零 分段体系结构是使8086的16位寄存器体系结构能够寻址一个完整兆字节(!)的地址空间(需要20

在实模式分段记忆模型中,分段总是从段落边界开始。段落的大小为16字节,因此段地址总是可以被16整除。段落边界上有段的原因/好处是什么?

8086有20个地址行。段被映射到前16位,留下底部4行或16个地址的偏移量。

这与其说是一个公理,不如说是一个公理-8086的实模式分段模型是在硬件级别设计的,因此段寄存器指定了段边界

段寄存器指定8086的20位地址空间的上16位的基址,该基址的下4位本质上被强制为零

分段体系结构是使8086的16位寄存器体系结构能够寻址一个完整兆字节(!)的地址空间(需要20位寻址)的一种方法

对于更多的历史,英特尔在x86体系结构中采取的下一步是从直接定义基址中提取段寄存器。这就是286保护模式,其中段寄存器持有一个“选择器”,该选择器不是定义物理基址的位,而是一组描述符表的索引,这些描述符表包含有关物理地址、访问物理内存的权限和其他信息


在现代32位或更大的x86处理器中,段寄存器仍然可以做到这一点。但由于地址偏移能够指定完整的32位寻址(或x64处理器上的64位寻址),页表能够在选择器定义的段内提供虚拟内存语义,编程模型基本上不需要在应用程序级别操纵段寄存器。在大多数情况下,操作系统只需设置一次段寄存器,无需其他任何处理。因此程序员通常不需要知道它们的存在。

段寄存器存储该段开始的内存位置的地址。但段寄存器存储16位信息。通过在地址的右端追加4位0,将16位转换为20位。如果一个段寄存器包含1000H,那么它将左移到10000H。现在是20位

转换时,我们在地址的末尾添加了4位0。因此,内存中的每个段都必须以最后4位为0的内存位置开始。

例如:

如果一个段从10001H内存位置开始,我们无法访问它,因为最后4位不是0。
段寄存器中的任何地址将在右端附加4位,以转换为20位。所以没有办法访问这样的地址。

需要一个“非编程问题”关闭。嗯。。不完全是,我正在Linux中使用逐步汇编语言,我就是不明白为什么要在段落边界上保留一个段。@帕格:这还不是编程问题。这是一个硬件问题。@John-我认为理解平台的寻址机制与编程有关。@Michael:硬件寄存器、DMA控制器等呢?他在写设备驱动程序代码吗?他为什么要编写real mode?这让我觉得这是一项他永远不会停止编程的研究。请注意,在某些情况下,段会回来,例如在Linux中实现线程本地存储。线程局部变量通过固定偏移量访问,但使用
gs
段寄存器,内核为每个线程设置不同的寄存器。同样,编译器在不打扰程序员的情况下处理这些数据。@thomasborninwindows也使用fs/gs来定位线程本地数据,称为。(在内核模式下,它们实际上定位一个称为的每CPU数据结构。)