在实践中,当前的硬件(例如 x86-64 PC、ARM 平板电脑,...)不再使用基址和限制寄存器(但i286使用了),但有一个MMU。
阅读有关MMU、分页、分段错误、虚拟内存、虚拟地址空间和操作系统的信息:三个简单的部分(可免费下载)
但是,当请求的地址实际上超出程序分配的内存空间时,有哪些示例?
用户空间中的任何类型的分段错误,特别是取消引用指针(或某些“未初始化”指针变量,其中包含地址空间之外的随机位模式)。此类错误在 C 程序(在用户空间)中很常见。对于一个简化的例子:NULL
int *ptr = NULL;
/// some long code or execution which does not change the `ptr` value
*ptr = 34; // SEGMENTATION FAULT
内核代码应该是可信的,并且不会出现任何分段错误(通过假设)。内核代码行为不端和取消引用无效地址会使计算机崩溃。
(在实践中,像 Linux 这样的大内核有一些代码可能会“部分”处理内核某些部分中的分段错误,例如某些驱动程序;但一般的想法是内核代码应该是可信的并且没有错误)。
顺便说一句,你的问题没有提到DMA(但你的评论有)。在实践中,DMA仅由内核管理(例如物理磁盘 I/O),内核在配置和启动它之前确保整个块地址都是有效的(并且分页)。因此,实际上 DMA 中的错误地址永远不会发生(取决于硬件 DMA 可以使用物理地址还是虚拟地址)。更一般地说,内核应该避免像分段错误或其他类型的错误地址这样的错误:用户空间可能有错误的地址(当这种情况发生时内核会产生分段错误,并且在 Unix 上会向应用程序发出一些SIGSEGV
信号),但是内核空间应该是只使用好地址的可信代码。