想象一台32位x86计算机,内存不足3 GB,CPU设置为禁用分页和扁平段描述符(0x0
作为基础,0xffffffff
作为数据和代码的有效限制)。
当0环中的指令试图使用mov
指令引用没有任何内存地址支持的物理地址时,会发生什么?
QEMU仿真只是由于一个类似"致命:试图在RAM或ROM之外执行代码"的错误而暂停。
这些异常与内存问题有关:
- 它不应该是"Segment Not Present(
#NP
)":它只在加载段寄存器时发生,但我实际上可以毫无问题地加载扁平段 - 不应生成"堆栈故障(
#SS
)",因为代码没有引用堆栈 - "一般保护(
#GP
)"不应该发生,因为代码在0环中运行,并且段被设置为允许访问每个物理地址 - 寻呼被禁用,所以它也不是"页面故障(
#PF
)"> - 而且它不是对齐问题,所以它不应该触发"对齐检查(
#AC
)">
我没有选择了,我不知道该怎么办。
如果禁用分页,并且当前段的限制为4GiB(在32位模式下),则没有"不存在"的地址:
在这种情况下,所有2^32个可能的地址都存在,并且可以读取和写入。
如果对没有RAM、ROM等的地址进行读写操作,会发生什么情况取决于CPU外部的硬件,而不是CPU本身。
对这样一个地址的写入操作通常会被忽略,而读取操作通常会导致无感测值(在大多数PC上,"全一"值,如0xFF、0xFFFF、0xFFFFFFFF)。
从理论上讲,这种地址访问可能会导致中断,甚至导致计算机崩溃,具体取决于地址。然而,这不是由CPU本身完成的,而是由其他硬件组件完成的。
在这样一个地址上执行代码基本上只是从该地址读取访问。
我的理解是,非分页内存访问直接进入总线,导致未定义的行为(取决于芯片组、总线类型等)——请参阅手动探测
注意:尝试读/写不存在的内存永远不会出错——这一点很重要:你不会得到有效的结果,但也不会出错。