当处理器尝试访问不存在的物理地址时会发生什么?

gfv*_*gfv 6 x86 assembly

想象一下32位x86计算机,内存少于3千兆字节,CPU设置为禁用分页和平面段描述符(0x0作为基础,0xffffffff作为数据和代码的有效限制).

当ring0中的指令尝试使用mov指令引用未被任何内存地址支持的物理地址时会发生什么?

QEMU模拟只是停顿了一个错误,如"致命:试图在RAM或ROM之外执行代码".

这些异常与内存问题有关:

  1. 它不应该是"Segment Not Present(#NP)":它只在加载段寄存器时发生,但我实际上可以毫无问题地加载扁平段.
  2. #SS不应生成"Stack Fault()",因为代码不引用堆栈.
  3. "General Protection(#GP)"不应该发生,因为代码在ring-0中运行,并且段设置为允许访问每个物理地址.
  4. 分页已禁用,因此它也不是"页面错误(#PF)".
  5. 并且它不是对齐问题,因此它不应该触发"对齐检查(#AC)".

我没有选择,我不知道会发生什么.

Aki*_*nen 5

我的理解是非分页内存访问直接进入总线,导致未定义的行为(取决于芯片组、总线类型等)——请参阅手动探测

注意:您永远不会因为尝试读/写不存在的内存而出错——理解这一点很重要:您不会得到有效的结果,但也不会得到错误。


Mar*_*nau 5

如果分页被禁用并且当前段的限制是 4GiB(在 32 位模式下),则没有“不存在”的地址:

在这种情况下,所有 2^32 个可能的地址都存在并且可以读取和写入。

如果对没有 RAM、ROM 等的地址进行读或写操作,会发生什么取决于 CPU 外部的硬件而不是 CPU 本身。

对此类地址的写操作通常会被忽略,而读操作通常会导致无意义值(在大多数 PC 上,“全 1”值如 0xFF、0xFFFF、0xFFFFFFFF)。

理论上这样的地址访问可能会导致中断甚至导致计算机崩溃,具体取决于地址。然而,这不是由 CPU 本身完成的,而是由其他硬件组件完成的。

在这样的地址上执行代码基本上只是对该地址的读取访问。