這是一個簡單的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