在使用一些操作码反汇编的 linux 内核的页面错误处理程序中,我看到在 x86 架构上,CALL 或 0xE8 指令偶尔会引发写入错误,并且 ESI 和 EDI 都是 NULL。我想知道这是否有特定原因,因为 CALL 需要一个内存地址并将 EIP 更改为该值,并且不需要页面,因为它只是 EIP + relative_offset。如果有人能澄清这一点,将不胜感激。
问问题
506 次
1 回答
8
该call
指令不只是改变eip
- 它还必须在改变eip
之前将当前(更新以指向下一条指令)写入堆栈。A jmp
-type 指令将按照您的建议执行,但call
稍有不同,您必须稍后才能ret
到达当前位置。
我不能确定,因为你没有给我们代码、完整的寄存器内容和页表(这将是一个问题的大量信息),但在我看来,最可能的解释是堆栈当前换了,需要买回来。
我最初想到的另一种可能性是您要跳转到的地址是非居民地址,但我认为这不会导致其call
本身出现故障。
当 CPU 试图获取下一条指令时,它会很快导致错误,但我认为这不是你的描述所表明的,因为:
- 你说它发生在
call
; 和 - 那将是读取错误,而不是写入错误。
esi
and值不是问题——edi
它们不参与.call
于 2011-06-23T20:31:38.120 回答