ブートで遊ぼっ!(6)

86系のPCをブートさせて遊んでみよう、というお話の6回目になります。テキストは『OSを書く:初歩から一歩ずつ』です。
環境はAMD64+Windows10+VMware Workstation 17 Player+Debian 12.4です。
今回はテキストの練習問題の4からです。

4. あるメモリアドレスの内容をプリントする

とかすると、axには_testのアドレスが入るわけで、あとはその中身を取り出して…取り出して?
どうやって?
というのがこの課題なんでしょう。
今までやってきたように、axとかに入っている値を扱いたい場合は上の書き方をします。で、それをアドレスとしてその中身を扱いたい場合[]で囲います。例えば今回の「_test」のアドレスの中身を取り出したい場合

とかして、_testのアドレスを取得した上で

とするわけです。1
欲しいのは0x15という値(41行目の_testのあとにdb命令?で定義しています)
alは1Byte。
mov命令は気が利かないので、alが1Byteなんだからbxのアドレスから1Byteだけ読むなんてことをしてくれません。なのでbxのアドレスから([bx])1Byteをalに移送してくれ(move byte alの部分)と指示します。
読み込めたら後は今まで通り、表示するだけ。

; boot.asm

mov ax, 0x07c0
mov ds, ax

mov ah, 0x0
mov al, 0x3
int 0x10

mov ax, 0x0000
mov bx, _test
mov byte al, [bx]
mov bx, ax

loop:

mov dx, 0
mov ax, bx
mov bx, 10
div bx
mov cx, dx
mov bx, ax
mov ah, 0x0e
mov al, dl
add al, 0x30
int 0x10

cmp bx, 0
jne loop


jmp hang

; end of proccess
;
hang:
jmp hang

_test: db 0x15, 0x00

times 510-($-$$) db 0

db 0x55
db 0xAA

PlayWithBoot.5.1

実行すると、こんな感じです。

5. BIOSを使ってディスクから何かを読み込んでみる

わたしはここで挫折しかかりました。ディスク読み込みのBIOSコールは調べられたんですが、パラメータが良くわかりませんでした。
ていうか、端的に言って、シリンダー、ヘッダー、セクターが理解できません。
なんか情報が錯綜しているというか、混じりあってる?
その上、ブートでセクタにはパーティションデーブルがあって、パーティションを特定したらFATがあって、みたいな?
お詫びと開き直りをするまで、結構かかりましたとも。ええ。
で、思ったわけです。
あのね?
わたしはディスクから読み込めればいいの!
FATなんて関係ないの!
と。
そもそもブートセクタは読めているわけで(だから動いてるし)、それはheaderが0、cylinderが0、sectorが1(sectorは1オリジンだそうです)以外にあり得ない。
ならば、それはheaderが0、cylinderが0、sectorを2にすれば読めるんじゃない?
さすがに2sectorの1KByteでheaderもcylinderも変わることないでしょ?
そういう予測のもとにソースを書きます。

; boot.asm

mov ax, 0x07c0
mov ds, ax
mov es, ax

mov ah, 0x0
mov al, 0x3
int 0x10


mov bx, 0x200   ; Destination address to read

mov ah, 0x02    ; Read Sectors From Drive
mov dl, 0x80    ; Drive
mov al, 0x01    ; Sectors To Read Count ;
mov ch, 0x00    ; Cylinder
mov cl, 0x02    ; Sector(starts from 1, not 0) ; set 2. becouse not need MBR
mov dh, 0x00    ; Head

int 0x13        ; Execute disk read

mov si, 0x0200
mov ah, 0x0E

loop:

lodsb

or al, al
jz loop_end

int 0x10

jmp loop

loop_end:


jmp hang


; end of proccess
;
hang:
jmp hang


times 510-($-$$) db 0

db 0x55
db 0xAA

test:
	db 'Hello 2nd sector!', 0x0a, 0x0d, 0x00

_padding:
        times 0x0400-($-$$) db 0

PlayWithBoot.5.2

さて、動かしてみましょう。
こういうのってワクワクしますよねw

はい。無事に動きました。

今回はここまでです。
なんだか、何かをやり遂げた気がします^^

《2024/5/9 1:18:24》

  1. mov al, [_test]とか書けた気がする…。 ↩︎

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です