我并没有实际问题,而是希望澄清一下内容问题。假设我们有一个微内核(PC Intel x86;32位受保护模式),它具有工作的中断描述符表(IDT)和每个CPU异常的中断服务例程(ISR)。当出现除以零
异常时,成功调用了ISR。
global ir0
extern isr_handler
isr0:
cli
push 0x00 ; Dummy error code
push %1 ; Interrupt number
jmp isr_exc_handler
isr_exc_handler:
; Save the current processor state
pusha
mov ax, ds
push eax
mov ax, 0x10 ; Load kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Push current stack pointer
mov eax, esp
push eax
call isr_handler ; Additional C/C++ handler function
pop eax ; Remove pushed stack pointer
pop ebx ; Restore original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa
add esp, 0x08 ; Clean up pushed error code and ISR number
sti
iret
问题在于中断一再发生。结果是,中断服务程序被一遍又一遍地调用。通过试错,我发现触发异常的代码行
int x = 5 / 0
在循环中执行,因此指令指针(EIP)没有递增。当我手动递增压入堆栈的IP值时,就会出现预期的行为。CPU随后执行恶意代码行之后的下一条指令。当然,在ISR被调用一次后。
我的实际问题是:ISR是否需要递增IP?还是这是“CPU/硬件”的责任?正确的移动方式是什么?