34ー42日目 - OS自作入門3日目のアセンブラ実装(harib00a~harib00b) 2016/5/25, 27, 30, 31, 2016/6/1, 2, 4, 6, 7

OS自作入門3日目のアセンブラ実装(harib00a~harib00b)

2日目のアセンブラ

アセンブラを実装する上では、この2日目のコードが一番の難関でした。

主なオペコードたち

  • JMP:以下の部分に注目して欲しいです。
    JMP entryと、アセンブラが書かれています。これは次のentryというラベルまで78byteあることを指しています。
  •         JMP     entry           ; eb4e
                                    ; 上記 0x4e(78d, 4e自身から見て次のentryまで78byteある)
  • JMP:次に以下の部分に注目して欲しいです。
    putloop: というラベルにジャンプする必要があるので JMP putloopと書くと-18byteと指し示すことになります。
  • putloop:
            MOV     AL,[SI]         ; 8a04
            ADD     SI,1            ; 83c601
            CMP     AL,0            ; 3c00
            JE      fin             ; 7409
            MOV     AH,0x0e         ; b40e
            MOV     BX,15           ; bb0f00
            INT     0x10            ; cd10
            JMP     putloop         ; ebee => 0xee(-18d) ; 符号あり1byteの0xeeは10進数で-18です。ここで試してみて → http://hogehoge.tk/tool/number.html
  • リンク先でrel8, rel16, rel32という表記で示される相対オフセットとは、つまりはそういうことです。
  • 参考:Tips IA32(x86)汎用命令一覧
  • 参考:2進数、8進数、10進数、16進数相互変換ツール

  • MOV:この表記も覚えておくべきでしょう。
    MOV AL,[SI]と、アセンブラが書かれています。これは[SI]がレジスタではなくメモリであることを示しています。
    メモリにあるか、レジスタにあるか、それとも即値かでニーモニックは大きく変化します。
    詳しくは"80x86 Opcodes"のサイトにあるMOV命令のニーモニック変化表を見てください。大体のところ、
    Reg: レジスタ
    Mem: メモリ
    Acc: アキュムレータ
    Imm: 即値
    Seg: セグメントレジスタ
    ってな具合です。この辺についてはOS自作入門にも解説されていますね。(流石にその実装方法までは書かれてませんが…)
  •         MOV     AL,[SI]         ; 8a04
  • 参考:80x86 Opcodes
; hello-os
; TAB=4

        ORG     0x7c00          ; ORGはバイナリには現れない

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

        JMP     entry           ; eb4e
                                ; 上記 0x4e(78d, 4e自身から見て次のentryまで78byteある)
        DB      0x90            ; 90
        DB      "HELLOIPL"      ; 48454c4c4f49504c
        DW      512             ; 0002
        DB      1               ; 01
        DW      1               ; 0100
        DB      2               ; 02
        DW      224             ; e000
        DW      2880            ; 400b
        DB      0xf0            ; f0
        DW      9               ; 0900
        DW      18              ; 1200
        DW      2               ; 0200
        DD      0               ; 00000000
        DD      2880            ; 400b0000
        DB      0,0,0x29        ; 000029
        DD      0xffffffff      ; ffffffff
        DB      "HELLO-OS   "   ; 48454c4c4f2d4f53202020
        DB      "FAT12   "      ; 4641543132202020
        RESB        18          ; 000000000000000000000000000000000000

; プログラム本体

entry:
        MOV     AX,0            ; b80000
        MOV     SS,AX           ; 8ed0
        MOV     SP,0x7c00       ; bc007c
        MOV     DS,AX           ; 8ed8
        MOV     ES,AX           ; 8ec0

        MOV     SI,msg          ; be747c
putloop:
        MOV     AL,[SI]         ; 8a04
        ADD     SI,1            ; 83c601
        CMP     AL,0            ; 3c00
        JE      fin             ; 7409
        MOV     AH,0x0e         ; b40e
        MOV     BX,15           ; bb0f00
        INT     0x10            ; cd10
        JMP     putloop         ; ebee => 0xee(-18d)
fin:
        HLT                     ; f4
        JMP     fin             ; ebfd

msg:
        DB      0x0a, 0x0a      ; 0a0a
        DB      "hello, world"  ; 68656c6c6f2c20776f726c64
        DB      0x0a            ; 0a
        DB      0               ; 00
        RESB    0x7dfe-$        ; 0x7dfeまで0x00
        DB      0x55, 0xaa      ; 55aa

; 後はまあいいですよね…

        DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB    4600
        DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
        RESB    1469432

3日目のアセンブラ

実は3日目の最初はあまり新出のオペコードがないです。リンク先を参照すればすべて実装できます。

3日目のアセンブラで新出のオペコード

  • JAE, JNC, JC, JE

参考:Jcc命令(Jump If Condition Is Met)

; haribote-ipl
; TAB=4

        ORG     0x7c00          ; ORGはバイナリには現れない

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

        JMP     entry           ; eb4e
        DB      0x90            ; 90
        DB      "HARIBOTE"      ; 48415249424f5445
        DW      512             ; 0002
        DB      1               ; 01
        DW      1               ; 0100
        DB      2               ; 02
        DW      224             ; e000
        DW      2880            ; 400b
        DB      0xf0            ; f0
        DW      9               ; 0900
        DW      18              ; 1200
        DW      2               ; 0200
        DD      0               ; 00000000
        DD      2880            ; 400b0000
        DB      0,0,0x29        ; 000029
        DD      0xffffffff      ; ffffffff
        DB      "HARIBOTEOS "   ; 48415249424f54454f5320
        DB      "FAT12   "      ; 4641543132202020
        RESB    18              ; 000000000000000000000000000000000000

; プログラム本体

entry:
        MOV     AX,0            ; b80000
        MOV     SS,AX           ; 8ed0
        MOV     SP,0x7c00       ; bc007c
        MOV     DS,AX           ; 8ed8   // ここまでは同じ

; ディスクを読む

        MOV     AX,0x0820       ; b82008
        MOV     ES,AX           ; 8ec0
        MOV     CH,0            ; b500
        MOV     DH,0            ; b600
        MOV     CL,2            ; b102

        MOV     AH,0x02         ; b402
        MOV     AL,1            ; b001
        MOV     BX,0            ; bb0000
        MOV     DL,0x00         ; b200
        INT     0x13            ; cd13
        JC      error           ; 7203

; 読み終わったけどとりあえずやることないので寝る

fin:
        HLT                     ; f4
        JMP     fin             ; ebfd

error:
        MOV     SI,msg          ; be8a7c
putloop:
        MOV     AL,[SI]         ; 8a04
        ADD     SI,1            ; 83c601
        CMP     AL,0            ; 3c00
        JE      fin             ; 74f1
        MOV     AH,0x0e         ; b40e
        MOV     BX,15           ; bb0f00
        INT     0x10            ; cd10
        JMP     putloop         ; ebee
msg:
        DB      0x0a, 0x0a      ; 0a0a
        DB      "load error"    ; 6c6f6164206572726f72
        DB      0x0a            ; 0a
        DB      0               ; 00

        RESB    0x7dfe-$        ; 0x7dfeまで0x00

        DB      0x55, 0xaa      ; 55aa
; haribote-ipl
; TAB=4

        ORG     0x7c00          ; ORGはバイナリには現れない

; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述

        JMP     entry           ; eb4e
        DB      0x90            ; 90
        DB      "HARIBOTE"      ; 48415249424f5445
        DW      512             ; 0002
        DB      1               ; 01
        DW      1               ; 0100
        DB      2               ; 02
        DW      224             ; e000
        DW      2880            ; 400b
        DB      0xf0            ; f0
        DW      9               ; 0900
        DW      18              ; 1200
        DW      2               ; 0200
        DD      0               ; 00000000
        DD      2880            ; 400b0000
        DB      0,0,0x29        ; 000029
        DD      0xffffffff      ; ffffffff
        DB      "HARIBOTEOS "   ; 48415249424f54454f5320
        DB      "FAT12   "      ; 4641543132202020
        RESB    18              ; 000000000000000000000000000000000000

; プログラム本体

entry:
        MOV     AX,0            ; b80000
        MOV     SS,AX           ; 8ed0
        MOV     SP,0x7c00       ; bc007c
        MOV     DS,AX           ; 8ed8

; ディスクを読む

        MOV     AX,0x0820       ; b82008
        MOV     ES,AX           ; 8ec0
        MOV     CH,0            ; b500
        MOV     DH,0            ; b600
        MOV     CL,2            ; b102

        MOV     SI,0            ; be0000
retry:
        MOV     AH,0x02         ; b402
        MOV     AL,1            ; b001
        MOV     BX,0            ; bb0000
        MOV     DL,0x00         ; b200
        INT     0x13            ; cd13
        JNC     fin             ; 7310
        ADD     SI,1            ; 83c601
        CMP     SI,5            ; 83fe05
        JAE     error           ; 730b
        MOV     AH,0x00         ; b400
        MOV     DL,0x00         ; b200
        INT     0x13            ; cd13
        JMP     retry           ; ebe3

; 読み終わったけどとりあえずやることないので寝る

fin:
        HLT                     ; f4
        JMP     fin             ; ebfd

error:
        MOV     SI,msg          ; be9d7c
putloop:
        MOV     AL,[SI]         ; 8a04
        ADD     SI,1            ; 83c601
        CMP     AL,0            ; 3c00
        JE      fin             ; 74f1
        MOV     AH,0x0e         ; b40e
        MOV     BX,15           ; bb0f00
        INT     0x10            ; cd10
        JMP     putloop         ; ebee
msg:
        DB      0x0a, 0x0a      ; 0a0a
        DB      "load error"    ; 6c6f6164206572726f72
        DB      0x0a            ; 0a
        DB      0               ; 00

        RESB    0x7dfe-$        ; 0x7dfeまで0x00

        DB      0x55, 0xaa      ; 55aa