Yabu.log

ITなどの雑記

30日OS自作本2日目

ちょっと詰まっても読み進めれば解決することがわかりました。

helloos.nas のコメント部分が文字化けしてしまいました。

nkf*1が入ってなかったのでとりあえずbrew install nkfで入れて文字コードを調べる。

$ nkf --guess helloos.nas 
Shift_JIS (CRLF)

Shift_JISらしい。

よくわかんないこと

ORG

day1の内容をわかりやすいように描き直しましょう、とありますが、 ORG命令に相当するものはday1のアセンブラにはない

アセンブラとバイナリ(DBで書き込んだ16進数)との対応(解決)

特に説明なく以下のDB命令が下のアセンブラに変換されているようだけど対応がいまいちわからない。

--(中略)--
; プログラム本体

        DB      0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
        DB      0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
        DB      0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
        DB      0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
        DB      0xee, 0xf4, 0xeb, 0xfd
; プログラム本体

entry:
        MOV     AX,0            ; レジスタ初期化
        MOV     SS,AX
        MOV     SP,0x7c00
        MOV     DS,AX
        MOV     ES,AX

        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1            ; SIに1を足す
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e         ; 一文字表示ファンクション
        MOV     BX,15           ; カラーコード
        INT     0x10            ; ビデオBIOS呼び出し
        JMP     putloop
fin:
        HLT                     ; 何かあるまでCPUを停止させる
        JMP     fin             ; 無限ループ

後述のnaskが生成したipl.listを読んで自己解決しました。

ラベルとアドレスの対応(解決)

なぜentryが0x7c50なのか、msgが0x7c74なのかわからない。 多分命令の長さを足していくとORGで書き込んだ0x7c00からラベルまで50、74の長さに相当する命令が詰まっているからなんだろうけど。

後述のnaskが生成したipl.listで解決しました。

nask以外のツールを使うことによりmakefileの内容が一部変わった

helloos3のmakefile

run :
    ../../z_tools/nask helloos.nas helloos.img
    cp helloos.img ../../z_tools/qemu/fdimage0.bin
    make -C ../../z_tools/qemu

helloos4のmakefile

ipl.bin : ipl.nas Makefile
    ../../z_tools/nask ipl.nas ipl.bin ipl.lst

helloos.img : ipl.bin Makefile
    ../../z_tools/edimg   imgin:../../z_tools/fdimg0at.tek \
        wbinimg src:ipl.bin len:512 from:0 to:0   imgout:helloos.img

img :
    make -r helloos.img

run :
    make img
    cp helloos.img ../../z_tools/qemu/fdimage0.bin
    make -C ../../z_tools/qemu
$ make run
make img
make -r helloos.img
../../z_tools/nask ipl.nas ipl.bin ipl.lst
../../z_tools/edimg   imgin:../../z_tools/fdimg0at.tek \
        wbinimg src:ipl.bin len:512 from:0 to:0   imgout:helloos.img
cp helloos.img ../../z_tools/qemu/fdimage0.bin
make -C ../../z_tools/qemu
qemu-system-i386 -L . -m 32 -localtime -vga std -fda fdimage0.bin
WARNING: Image format was not specified for 'fdimage0.bin' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.

以前のものは - naskでアセンブル(アセンブラ言語をバイナリに変換)してimgファイルを作成 - qemuの特定のフォルダにimgファイルを配置 - qemuを起動

みたいな感じだけど今回からちょっと手順が増えて - naskでアセンブル - edimgをディスクイメージ管理ツールとして仕様(ブートセクタ以外〜の箇所のソースが生成される?) - qemuの特定のフォルダにimgファイルを配置 - qemuを起動

という感じに変わった

アセンブル時にできるipl.listってなに?

catコマンドでのぞいて見たら機械語 - アセンブラ言語の対応ファイルっぽい(しかもアドレス付き)

$ cat ipl.lst | nkf -w
     1 00000000                                 ; hello-os
     2 00000000                                 ; TAB=4
     3 00000000                                 
     4                                                  ORG     0x7c00          ; このプログラムがどこに読み込まれるのか
     5 00007C00                                 
     6 00007C00                                 ; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述
     7 00007C00                                 
     8 00007C00 EB 4E                                   JMP     entry
     9 00007C02 90                                      DB      0x90
    10 00007C03 48 45 4C 4C 4F 49 50 4C                 DB      "HELLOIPL"      ; ブートセクタの名前を自由に書いてよい(8バイト)
    11 00007C0B 0200                                    DW      512             ; 1セクタの大きさ(512にしなければいけない)
    12 00007C0D 01                                      DB      1               ; クラスタの大きさ(1セクタにしなければいけない)
    13 00007C0E 0001                                    DW      1               ; FATがどこから始まるか(普通は1セクタ目からにする)
    14 00007C10 02                                      DB      2               ; FATの個数(2にしなければいけない)
    15 00007C11 00E0                                    DW      224             ; ルートディレクトリ領域の大きさ(普通は224エントリにする)
    16 00007C13 0B40                                    DW      2880            ; このドライブの大きさ(2880セクタにしなければいけない)
    17 00007C15 F0                                      DB      0xf0            ; メディアのタイプ(0xf0にしなければいけない)
    18 00007C16 0009                                    DW      9               ; FAT領域の長さ(9セクタにしなければいけない)
    19 00007C18 0012                                    DW      18              ; 1トラックにいくつのセクタがあるか(18にしなければいけない)
    20 00007C1A 0002                                    DW      2               ; ヘッドの数(2にしなければいけない)
    21 00007C1C 00000000                                DD      0               ; パーティションを使ってないのでここは必ず0
    22 00007C20 00000B40                                DD      2880            ; このドライブ大きさをもう一度書く
    23 00007C24 00 00 29                                DB      0,0,0x29        ; よくわからないけどこの値にしておくといいらしい
    24 00007C27 FFFFFFFF                                DD      0xffffffff      ; たぶんボリュームシリアル番号
    25 00007C2B 48 45 4C 4C 4F 2D 4F 53 20 20           DB      "HELLO-OS   "   ; ディスクの名前(11バイト)
       00007C35 20 
    26 00007C36 46 41 54 31 32 20 20 20                 DB      "FAT12   "      ; フォーマットの名前(8バイト)
    27 00007C3E 00 00 00 00 00 00 00 00 00 00           RESB    18              ; とりあえず18バイトあけておく
       00007C48 00 00 00 00 00 00 00 00 
    28 00007C50                                 
    29 00007C50                                 ; プログラム本体
    30 00007C50                                 
    31 00007C50                                 entry:
    32 00007C50 B8 0000                                 MOV     AX,0            ; レジスタ初期化
    33 00007C53 8E D0                                   MOV     SS,AX
    34 00007C55 BC 7C00                                 MOV     SP,0x7c00
    35 00007C58 8E D8                                   MOV     DS,AX
    36 00007C5A 8E C0                                   MOV     ES,AX
    37 00007C5C                                 
    38 00007C5C BE 7C74                                 MOV     SI,msg
    39 00007C5F                                 putloop:
    40 00007C5F 8A 04                                   MOV     AL,[SI]
    41 00007C61 83 C6 01                                ADD     SI,1            ; SIに1を足す
    42 00007C64 3C 00                                   CMP     AL,0
    43 00007C66 74 09                                   JE      fin
    44 00007C68 B4 0E                                   MOV     AH,0x0e         ; 一文字表示ファンクション
    45 00007C6A BB 000F                                 MOV     BX,15           ; カラーコード
    46 00007C6D CD 10                                   INT     0x10            ; ビデオBIOS呼び出し
    47 00007C6F EB EE                                   JMP     putloop
    48 00007C71                                 fin:
    49 00007C71 F4                                      HLT                     ; 何かあるまでCPUを停止させる
    50 00007C72 EB FD                                   JMP     fin             ; 無限ループ
    51 00007C74                                 
    52 00007C74                                 msg:
    53 00007C74 0A 0A                                   DB      0x0a, 0x0a      ; 改行を2つ
    54 00007C76 68 65 6C 6C 6F 2C 20 77 6F 72           DB      "hello, world"
       00007C80 6C 64 
    55 00007C82 0A                                      DB      0x0a            ; 改行
    56 00007C83 00                                      DB      0
    57 00007C84                                 
    58 00007C84 00 00 00 00 00 00 00 00 00 00           RESB    0x7dfe-$        ; 0x7dfeまでを0x00で埋める命令
       00007C8E 00 00 00 00 00 00 00 00 00 00 
       00007C98 00 00 00 00 00 00 00 00 00 00 
       00007CA2 00 00 00 00 00 00 00 00 00 00 
       00007CAC 00 00 00 00 00 00 00 00 00 00 
       00007CB6 00 00 00 00 00 00 00 00 00 00 
       00007CC0 00 00 00 00 00 00 00 00 00 00 
       00007CCA 00 00 00 00 00 00 00 00 00 00 
       00007CD4 00 00 00 00 00 00 00 00 00 00 
       00007CDE 00 00 00 00 00 00 00 00 00 00 
       00007CE8 00 00 00 00 00 00 00 00 00 00 
       00007CF2 00 00 00 00 00 00 00 00 00 00 
       00007CFC 00 00 00 00 00 00 00 00 00 00 
       00007D06 00 00 00 00 00 00 00 00 00 00 
       00007D10 00 00 00 00 00 00 00 00 00 00 
       00007D1A 00 00 00 00 00 00 00 00 00 00 
       00007D24 00 00 00 00 00 00 00 00 00 00 
       00007D2E 00 00 00 00 00 00 00 00 00 00 
       00007D38 00 00 00 00 00 00 00 00 00 00 
       00007D42 00 00 00 00 00 00 00 00 00 00 
       00007D4C 00 00 00 00 00 00 00 00 00 00 
       00007D56 00 00 00 00 00 00 00 00 00 00 
       00007D60 00 00 00 00 00 00 00 00 00 00 
       00007D6A 00 00 00 00 00 00 00 00 00 00 
       00007D74 00 00 00 00 00 00 00 00 00 00 
       00007D7E 00 00 00 00 00 00 00 00 00 00 
       00007D88 00 00 00 00 00 00 00 00 00 00 
       00007D92 00 00 00 00 00 00 00 00 00 00 
       00007D9C 00 00 00 00 00 00 00 00 00 00 
       00007DA6 00 00 00 00 00 00 00 00 00 00 
       00007DB0 00 00 00 00 00 00 00 00 00 00 
       00007DBA 00 00 00 00 00 00 00 00 00 00 
       00007DC4 00 00 00 00 00 00 00 00 00 00 
       00007DCE 00 00 00 00 00 00 00 00 00 00 
       00007DD8 00 00 00 00 00 00 00 00 00 00 
       00007DE2 00 00 00 00 00 00 00 00 00 00 
       00007DEC 00 00 00 00 00 00 00 00 00 00 
       00007DF6 00 00 00 00 00 00 00 00 
    59 00007DFE                                 
    60 00007DFE 55 AA                                   DB      0x55, 0xaa

まとめ

*1:大学時代は演習室=Linux、自宅=Mac、授業=Windowsでかなりお世話になりました。。。