在x86机器上,当中断被触发时,CR3是否会改变(而不仅仅是EIP的值)?
答案 0 :(得分:3)
当发生中断或异常时,处理器会保存以下状态(参见 Intel 64和IA-32架构软件开发人员手册第3卷(3A,3B& 3C):系统编程指南,6.12 .1。):
如果DPL(目标权限级别)等于CPL(当前权限级别),则在将控制权交给中断处理程序之前,将以下寄存器和可能的错误代码推送到当前堆栈: / p>
EFLAGS, CS, EIP
如果另一方面DPL低于CPL,那么除了上述寄存器之外,SS
和ESP
寄存器被推送到另一个堆栈(在TSS中指定)。
由于处理器必须使操作系统能够恢复中断过程的状态,因此处理器不可能自行更改上述寄存器以外的任何其他状态。因此,CR3
不已更改。
这意味着必须在可能发生中断的每个虚拟地址空间中访问中断处理程序的代码。因此,并且因为这样的处理程序通常从内核调用其他代码,所以大多数内核将自己的代码和数据的很大一部分映射到每个进程的地址空间,从而减少了每个进程的可用内存空间。通常这种映射是在"上端"可寻址内存空间,大约3GB。
在很久以前我写过的一个业余爱好内核中,我采取了尝试保持进程的地址空间尽可能大的方法,因此我只映射了中断处理程序以及一些代码和所需的数据以更改为在将中断实际处理到进程的地址空间之前,专用内核地址空间。事实证明这是相当困难的,只有一个可疑的好处,这就是为什么我猜大多数系统都不采用这种方法。
如果中断描述符表中有任务门描述符,那么当该中断触发硬件任务开关时,会将处理器的状态保存到当前的TSS并从中加载状态任务门引用的TSS。这包括加载CR3
寄存器的值,从而改变虚拟地址空间(见上述手册的7.3。)。
在64位模式下,不支持任务切换[..]
[上面提到的英特尔手册,7.2.3]
答案 1 :(得分:2)
可能。您可能有一项专门用于中断服务的任务。它可能具有与其中断的任务不同的CR3值(在任务状态段(AKA TSS)中存在CR3的字段)。因此,您可能最终会在每次中断时切换两次CR3,即每次任务切换。