memory-management - 如何使用基址寄存器、限制寄存器和重定位寄存器?

标签 memory-management operating-system

我对MMU(内存管理单元)地址转换过程的理解

-> 逻辑地址:由 cpu.programmer 生成,关注这个地址。

-> 虚拟地址:驻留在硬盘中,作为一个页面。

-> 物理地址:驻留在 RAM 中。这是实际地址。

1:cpu生成逻辑地址并发送给MMU。

2:MMU将逻辑地址翻译成虚拟地址,再翻译成物理地址,将物理地址发送到RAM。

3:当RAM已满时,将没有快速使用的页面返回到硬盘,为其他页面(进程)分配内存。

我的问题是:
1)Relocation寄存器的值加在哪里?
2)谁来决定搬迁寄存器的值(value)?
3) Base register 和 Limit register 有什么用,怎么用?
4)逻辑地址在哪里消失?

如果有人能回答它,那将不胜感激。
请求,让我知道在这个话题上的任何误解。
-谢谢

最佳答案

我可以告诉你这在 x86 上是如何工作的。

所有非 64 位模式下的程序都使用由以下两项组合而成的地址:segment selector (为简洁起见,文本中经常省略“选择器”,这可能会造成混淆)和 offset .这个selector:offset对被称为 logical address .

选择器部分并不总是在代码中明确指定或操作,因为 CPU 具有段寄存器的“默认”关联,其中包含具有特定指令或特定指令编码的选择器。在 32 位模式下操作选择器也是不常见的,但在 16 位代码中经常是必需的。
virtual address由“直接”(在 real8086 virtual 模式下)或“间接”(在 protected 模式下)的逻辑地址构成。
"Direct" virtual address = selector * 16 + offset .
"Indirect" virtual address = 段描述符表[selector ].基地 + offset .

SegmentDescriptorTable 是 Global Descriptor Table (AKA GDT ) 或本地描述符表 (AKA LDT )。它由操作系统设置并描述各种内存段的位置和大小。 selector用于选择表中的段。 Base表的条目告诉段的开始(虚拟地址)。 Limit entry 告诉段大小(通常;细节有点复杂)。

当程序尝试使用偏移量访问内存时,导致访问超出段末尾(CPU 比较 offsetLimit ),CPU 生成 exception并且操作系统通常通过终止程序来处理它。

顺便说一句,在 real/v86模式,即使虚拟地址是直接从 selector:offset 形成的, 还有一个 16 位的 Limit强加于偏移量,这就是为什么您需要使用不同的选择器来访问超过 64KB 的内存。
Base段描述符中的条目可用于将段与内存的其余部分隔离(Limit 在这里有帮助)或将整个段放置或移动到任意虚拟地址,而无需修改任何(或很多)它所属的程序(如果我们要移动一个段,显然数据必须在内存中移动)。基本上,它可以用于重定位目的。在 real/v86搬迁模式selector被改变。
virtual address可以进一步翻译成physical address如果 CPU 在 protected mode 中运行并设置了page tables .如果没有页表,则物理地址与虚拟地址相同。转换在称为 pages 的物理内存块和地址范围中完成。 (通常为 4KB)。

x86 CPU 上没有专用的重定位寄存器。可以通过调整来实现重定位:

  • CPU 寄存器或程序代码中的段选择器
  • GDT/LDT 中的段基地址
  • 程序代码中的偏移量
  • 页表中的物理地址

  • 至于virtual address : reside in the hard disk , as a pages ,我不确定你到底想说什么,但仅仅因为有虚拟到物理地址的转换,并不意味着还有虚拟磁盘内存。除了虚拟磁盘内存之外,翻译还有其他用途。并且地址驻留在 CPU 中以及您(和操作系统)代码将它们写入的任何位置,不一定在磁盘上。

    关于memory-management - 如何使用基址寄存器、限制寄存器和重定位寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9578772/

    相关文章:

    windows - 对 32 位 Windows 可执行文件使用/LARGEADDRESSAWARE 的缺点?

    c++ - std::vector 中如何管理动态内存?

    c - 在 C 中使用低级 api 重定向标准输出

    java - 像操作系统一样运行java应用程序

    algorithm - 测试 CPU 调度

    c++ - 如何避免在 C++ 中自动释放?

    Scala垃圾回收?

    c - 内存、指针和指向指针的指针

    windows - CreateTimerQueueTimer()设置的回调函数的调用线程是谁?

    c - while 查看 switch 语句的内部(双重中断)