よもぎのメモ帳

備忘録的な感じで技術的なことをストックしていきます。

よもぎのOS自作入門 20日目/30日

はじめに

これは2020年夏休み企画「30日でOS自作してみよう!」20日目の記事です。

企画についてはこちら

y0m0g1.hatenablog.com

昨日やったことを書いていきます。

昨日の進捗

f:id:y0m0g1:20200911133256p:plain
hello worldするアプリケーション

実行可能なファイルを呼び出してアプリケーションとして実行できるようにしました。

昨日やったこと

今回は説明するのがちょっと難しい気がします。

文字をコンソール画面上に表示するシステムコール*1を作り、アプリケーションから呼び出してみようというのが目標です。

アプリケーションで表示したい文字をレジスタに入れても、OSが用意している文字表示機能は受け取れないので*2レジスタに入れられた値をスタックに積むアセンブラを用意します。

最初エラーが発生していますが、OSの領域とアプリケーションの領域ではセグメンテーションが違うので、意識してCALL命令やRET命令をfar-CALL命令やfar-RET命令に置き換えます。

f:id:y0m0g1:20200911175008p:plain
はろわ

このシステムコールはmakeして、関数のマッピングを見て直接呼び出すメモリ番地を指定していましたが、 それだとOSに手を加えるたびにその値を変えなきゃいけなくなっちゃう。 回避方法としてIDT*3に登録します。

また、コマンドにない文字列を入力してEnterを押すと、その文字列をファイル名とする実行可能なファイルを実行するようにも変えました。 いままではhlt.hrbという名前をハードコーディングしていました。今回はhello.hrbという名前です。 拡張子があってもなくても.hrb形式のファイルを実行します。

f:id:y0m0g1:20200911175602p:plain
not hlt, hello

また先程は文字を表示するだけだったシステムコールを拡張して、文字列を表示するシステムコールも追加しました。 が、一部うまく行かないみたいなことがあって仕様なので、次回以降の課題です。

;hello.nas
[INSTRSET "i486p"]
[BITS 32]
    MOV     ECX,msg
    MOV     EDX,1 ;_put_charを指定
putloop:
    MOV     AL,[CS:ECX]
    CMP     AL,0
    JE      fin
    INT     0x40 ;syscall
    ADD     ECX,1
    JMP     putloop
fin:
    RETF
msg:
    DB      "Hello world!",0

;hello2.nas
[INSTRSET "i486p"]
[BITS 32]
    MOV     EDX,2 ;_put_strを指定
    MOV     EBX,msg
    INT     0x40 ;syscall
    RETF
msg:
    DB      "Hello world!",0

f:id:y0m0g1:20200911175743p:plain
helloはうまくいってhello2はうまくいかない

今日も一日頑張るぞい!

*1:本の筆者はAPIと言っている

*2:C言語でできているため

*3:interrupt descriptor table