我目前正在开发内核,在实现系统调用时遇到了一个神秘的问题。我这样编写第 0x80 个中断处理程序:
sys_call_s:
pushad
call sys_call
popad
iret
“sys_call”是做实际工作的 C 函数的名称。问题是:执行“int 0x80”的下一条指令时出现三重错误。例如,我在执行下面程序的第三行时出错,最后 bochs 将自行重置。
abc: mov eax,0 ; 0 means system call get_pid()
int 0x80
mov [pid_father],eax ; this is the instruction caused bochs to triple fault
mov eax,1 ; 1: fork()
int 0x80
jmp $
pid_father: dd 0
更奇怪的是,当我用“ret”代替“iret”指令时,程序运行良好,并在“jmp $”处自行旋转。
有谁知道我为什么会遇到这个问题?
[编辑] 现在我认为这个问题是由堆栈指针的错误地址引起的。我为这个进程映射了一个页面,这个页面的物理地址是0x401000,线性地址是0x800000(8M)。我已将此进程的堆栈指针设置为 0x800ff0,但每次我在 bochs 中使用“print-stack”命令时,输出都是:“物理地址不适用于线性 0x00801000”。我该如何解决?
[编辑] 现在我发现在这个过程中我无法访问数据。例如,当我将“mov [pid_father],eax”放在“int 0x80”之前时,bochs 会自行重置。为什么会这样?