私は現在カーネルを開発していますが、システム コールを実装するときに不可解な問題に遭遇します。0x80 番目の割り込みハンドラを次のように記述します。
sys_call_s:
pushad
call sys_call
popad
iret
「sys_call」は、実際の作業を行う C 関数の名前です。問題は、「int 0x80」の次の命令を実行するときに、トリプル フォルトが発生したことです。たとえば、以下のプログラムの 3 行目を実行するとエラーが発生し、最後に 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
さらに奇妙なことに、「iret」命令を「ret」に置き換えると、プログラムは正常に動作し、「jmp $」でスピンします。
なぜこの問題が発生したのか、誰にも分かりますか?
[編集] この問題は、スタック ポインタのアドレスが間違っていることが原因だと思います。このプロセス用にページをマップしました。このページの物理アドレスは 0x401000、線形アドレスは 0x800000(8M) です。このプロセスのスタック ポインターを 0x800ff0 に設定しましたが、bochs で「print-stack」コマンドを使用するたびに、「リニア 0x00801000 では物理アドレスを使用できません」という出力が表示されます。どうすれば修正できますか?
[編集] このプロセスでデータにアクセスできないことがわかりました。たとえば、「int 0x80」の前に「mov [pid_father],eax」を配置すると、bochs がリセットされます。なぜこれが起こったのですか?