在interrup内写入eip寄存器。英特尔IA32 PC架构

问题描述:

在中断中,我想以某种方式写入函数的地址,并在中断结束后将此地址写入EIP寄存器。但似乎我的程序在设置EIP注册后立即去到这个地址。
我用在interrup内写入eip寄存器。英特尔IA32 PC架构

jmp eax 

eax值进入EIP

你能建议我怎么做我想要的吗?应该有一种方法,因为上下文切换必须以某种方式工作。

我的目标CPU是Intel 80386(i386)(Intel IA32 PC架构)。

+0

用于处理中断的确切过程是什么?您应该使用'iret'从中断处理过程返回。没有更多的上下文,这个问题是无法回答的。 –

+2

当然,您应该只更新堆栈中的EIP。这将被'IRET'弹出。 – Jester

+0

“上下文切换”可能会为每个上下文单独堆叠。并保存寄存器值。如果你的中断是一个计时器,你可能会想稍后恢复中断的代码。不要只是跳到其他地方,忘记你来自哪里。 –

我假设你处于保护模式。

每个中断都会在堆栈中存储返回地址,当遇到iret指令时,它会跳转到该地址。

如果中断被触发,CPU会将返回地址(段选择符+偏移量)以及此后的eflags寄存器的内容压入堆栈。
因此,为了用其他值替换返回地址的偏移量,您需要将返回地址移动到esp + sizeof(eflags) = esp + 04h

在大会表示,英特尔的语法:

mov [esp + 04h], ret_addr 


现在,执行iret指令时,ISR会跳转到ret_addr所指向的代码。
但是,请注意,如果目标代码被ret(即函数)终止,则还需要推送堆栈上的返回地址。这是通过

  • push完成荷兰国际集团的偏移仅压入堆栈

,或者之前,即

  • push段选择荷兰国际集团到堆栈

右在上面的代码中指出。


+0

我相信它看起来合乎逻辑,我会尝试,谢谢 – KosTTTT

+0

如果它自动推动和弹出这些寄存器,那么我宁愿不去触摸这些寄存器。我只是将指针切换到堆栈,并且它自己弹出新的数据。 – KosTTTT

+0

@KosTTT我编辑了如何替换返回地址。希望这样更好。 – Downvoter