Operating system 分段如何工作以及如何从分段表计算物理内存地址
我正在讨论操作系统中的细分主题 我了解到,分段的概念之所以存在,是因为内存中加载的进程的地址空间中可能存在空闲空间 我将尝试先解释一下我从学习中了解到的一些事情。如果有任何错误,请纠正我 例如,如果不使用分段,则可能不是理想情况 我有一个进程,它的地址空间很小,加载到内存中。因为进程地址空间可能不会放在物理内存的开头。我们需要一些机制来转换程序代码的地址(代码段,从那里执行PC所指向的指令)到实际的物理内存地址。为此,我们使用硬件寄存器(MMU)来维护运行进程的基值和绑定值。基值是放置进程的物理内存的起始地址,绑定是运行进程的总大小或运行进程的最后一个地址。由于MMU是全局的,我们需要在上下文切换期间保存基/绑定值 所以这里Operating system 分段如何工作以及如何从分段表计算物理内存地址,operating-system,memory-address,virtual-memory,memory-segmentation,Operating System,Memory Address,Virtual Memory,Memory Segmentation,我正在讨论操作系统中的细分主题 我了解到,分段的概念之所以存在,是因为内存中加载的进程的地址空间中可能存在空闲空间 我将尝试先解释一下我从学习中了解到的一些事情。如果有任何错误,请纠正我 例如,如果不使用分段,则可能不是理想情况 我有一个进程,它的地址空间很小,加载到内存中。因为进程地址空间可能不会放在物理内存的开头。我们需要一些机制来转换程序代码的地址(代码段,从那里执行PC所指向的指令)到实际的物理内存地址。为此,我们使用硬件寄存器(MMU)来维护运行进程的基值和绑定值。基值是放置进程的物理
物理内存地址=虚拟内存地址+基址代码>
现在让我们假设有一个具有大地址空间的进程。我们需要一些机制,如分段,以便更好地利用可用空间,因为进程地址空间在堆和堆栈之间或代码和堆之间可能包含大量的可用空间
对于分段,我们为每个进程维护一个分段表(在上下文切换期间需要将该表存储在PCB中)
在分段中,我们为运行进程地址空间的每个逻辑段维护基值/绑定值。因此,理想情况下,我们为每个代码段、堆栈段和堆段维护基值/绑定值,并将这些值存储在段表中
所以段表应该看起来像这样
Segment | Base | Bounds
---------------------------
Code | 16K | 1K
Heap | 28K | 1K
Stack | 20K | 2K
0 |---------------------|
| OS |
| |
....
| |
| |
| |
16K |---------------------|
| (program code) |
| |
17K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
20K |---------------------|
| |
| |
| (stack) |
| |
22K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
28K |---------------------|
| |
| (heap) |
29K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
32K |---------------------|
物理内存可能是这样的
Segment | Base | Bounds
---------------------------
Code | 16K | 1K
Heap | 28K | 1K
Stack | 20K | 2K
0 |---------------------|
| OS |
| |
....
| |
| |
| |
16K |---------------------|
| (program code) |
| |
17K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
20K |---------------------|
| |
| |
| (stack) |
| |
22K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
28K |---------------------|
| |
| (heap) |
29K |---------------------|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxx free xxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxx|
32K |---------------------|
因此,如果处理器在执行代码指令时需要将虚拟内存地址转换为物理内存地址,那么它将如何知道选择哪个基值,因为段表中可能有许多基值
假设我们假设指令是更新某个堆栈变量。在这种情况下,它将如何选择堆栈的基值
所以物理内存地址=堆栈的基址+指令中的虚拟内存地址
除了外部碎片化之外,细分的缺点是什么
任何详细解释分段/分页/虚拟化概念的外部链接都会非常有用。在支持分段的处理器中,处理器应该有一个内部或外部寄存器,用于根据上下文选择正确的分段。这取决于处理器体系结构。据我所知,唯一支持细分的处理器是英特尔处理器
对于x86(请参阅)段寄存器/选择器,有cs
、ds
、ss
。处理器在执行指令时使用代码cs
段,数据段ds
带内存,除非您另有说明,或堆栈段ss
带堆栈指令
除了x86之外,大多数现代处理器只支持分页。因此,要统一内存管理,在大多数现代操作系统中都需要x86分段,并依靠分页来管理虚拟内存。分段是一个难题。这一直是一个难题。如果你想了解内存管理(特别是因为Intel最终放弃了64位模式的分段),我建议你学习一个没有分段的虚拟内存系统是如何工作的。这个问题似乎是离题的,因为它是关于计算机体系结构的设计和实现,而不是编程。如果你有一个程序不起作用,欢迎你在这里发布。也许更适合这类问题。