我一直在尝试按照James Molloy 的本教程创建一个 ISR 处理程序
,但我被卡住了。每当我抛出软件中断时,通用寄存器和数据段寄存器都会被推送到堆栈中,而 CPU 会自动推送变量。然后将数据段更改为 0x10(内核数据段描述符)的值,从而更改权限级别。然后在处理程序返回后,这些值被pop编辑。但是,无论何时ds更改中的值,都会抛出错误代码为 0x2544 的 GPE,几秒钟后 VM 会重新启动。(链接器和编译器 i386-elf-gcc ,汇编器 nasm)
我尝试在hlt指令之间放置指令以定位哪个指令正在抛出 GPE。在那之后,我能够找到“mov ds,ax”指令。我尝试了各种方法,例如删除由引导程序代码初始化的堆栈以删除代码的权限更改部分。我可以从公共存根返回的唯一方法是删除更改权限级别的代码部分,但是当我想转向用户模式时,我仍然希望它们保留。
这是我常用的存根:
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
xor eax,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
xor eax,eax …Run Code Online (Sandbox Code Playgroud)