这是一个简单的x86内联汇编实现。你有一个包装函数来改变堆栈,并调用你的真实例程。
const uint32_t interrupt_stack_size = 4096;
uint8_t interrupt_stack[interrupt_stack_size];
void interrupt_routine_wrap()
{
static int thread_esp;
// Stack grows towards lower addresses, so start at the bottom
static int irq_esp = (int) interrupt_stack + interrupt_stack_size;
// Store the old esp
asm mov dword ptr thread_esp, esp;
// Set the new esp
asm mov esp, dword ptr irq_esp;
// Execute the real interrupt routine
interrupt_routine();
// Restore old esp
asm mov esp, dword ptr thread_esp;
}
我完全无视这里的段寄存器(ss
),但不同的内存模型可能需要存储,随着sp
。
您可以通过使用setjmp
/longjmp
来读取/写入所有寄存器来摆脱内联汇编。这是一个更便携的方式来做到这一点。
另请注意,我在这里不保存任何寄存器,并且内联汇编可能会混淆编译器。也许值得在包装程序周围添加一对pusha
/popa
。如果将函数指定为interrupt
,编译器可能会为您执行此操作。检查生成的二进制文件是否确定。
这是什么编程语言? – JJJ
真实代码在C.我只是在这里放了一种伪代码。对于那个很抱歉。 – sniper
如何让变量'static'(取决于你有多少ram)? – vlp