在使用某些操作码反汇编的linux内核的页面错误处理程序中,我发现在x86架构上,CALL或0xE8指令偶尔会抛出写入错误,ESI和EDI都是NULL。我想知道是否有一个特定的原因,因为CALL占用一个内存地址,只是将EIP更改为该值,并且不需要页面,因为它只是EIP + relative_offset。如果有人能够清除这一点,将非常感激。
答案 0 :(得分:8)
call
指令不只更改eip
- 它还必须写入当前eip
(更新为指向下一条指令)在那次改变之前的堆栈。 jmp
类型的说明会按照您的建议行事,但call
稍有不同,因为您必须稍后ret
到当前位置。
我无法确定,因为你没有给我们代码,完整的注册内容和页面表( 是一个问题的大量信息),但它似乎我最有可能的解释是堆栈目前已经关闭,需要重新购买。
我最初想到的另一种可能性是你跳到的地址是非居民的,但我认为这不会导致call
本身的错误。
会在之后很快导致故障,因为CPU试图获取下一条指令,但我不认为这是您的描述所指示的,因为:
call
;和 esi
和edi
值不是问题 - 它们不参与call
。