DAY1
- バイナリファイル自体は2進数だが、それでは冗長になるので、 以下のように2進数⇒16進数に変換することで情報量を減らしている
DB命令
: data byte命令、ファイルの内容を1byteだけ直接書く。文字列も書けるよ!PRESS命令
: reserve byte 、引数 x byteを予約する、具体的には0x00を書きこんで埋めるDW命令
: data word、DB命令の仲間 word=16bit/2byteDD命令
: data double word、DB命令の仲間 word=32bit/4bit
DAY2
- ORG命令 = ORIGIN、機械語が実行時にPCのメモリのどこに読み込まれるのかを指定する
- JMP命令 = C言語でいうところのgo to
- MOV命令 = アセンブラで最もよく使う命令。代入。
- MOV AX,0 の場合、AX = 0; となる。
- 代表的なレジスタ、8個のレジスタで合計18byteを使用
- レジスタの類型
- 8bit
- 16bit
- 32bit
セグメントレジスタ
その後、フロッピーからBIOS的なものを起動するアセンブラなコードを写経する。 以下、処置の流れのメモ。
ORG命令で、0x7c00(16進数7C00 = 10進31744)を読み込まれるアドレス番地として指定
ORG 0x7c00 ; プログラムが読み込まれるメモリアドレスを指定
その次に出てくるのは、JMP命令。entryラベルにgo toする。
JMP entry
entryに入り、MOV AX,0で AX = 0; として処理される。0を値として入れることは初期化と呼ばれている。
entry:
MOV AX,0 ; レジスタ初期化
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX
MOV SI,msg
上記のentryラベルの区画の最後の「MOV SI,msg」において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
次のputloopラベルに移る。
最初の「MOV AL,[SI]」の「 [SI] 」はSIレジスタではなく、メモリ番地を指し示す。 例えばSIレジスタに987が値として格納されていれば、「987番地のメモリに格納された値を1byte取り出しALレジスタに代入(格納する)」となる 特に明示的に書かれていないが、
- MOV AL,[SI] 1ビット取り出し
- MOV BYTE AL,[SI] 8ビット取り出し
- MOV WORD AL,[SI] 16ビット取り出し
- MOV DWORD AL,[SI] 32ビット取り出し
となるらしい。
メモリの1区画の大きさについては、
メモリは基本、8bit(0か1を8個並べたもの)ごとに1区画として、1区画ごとにアドレス(番地)が振られている。
とのこと。
ADD SI,1 ; SIに1を足す
その次のADD命令は足し算となる。 ADD SI,1 は SI = SI + 1;
CMP AL,0
JE fin
ここは1セットの構文で、CMPが if ( AL == 0)
JEが then go to fin というような動きとなる。
JE は「jump if equal」の略称
INT 0x10 ; ビデオBIOS呼び出し
INT命令はinterrupt(ハードウェア割り込み?)を発行している?
以下を全て実行すると、BIOS経由で画面に文字が出力できるとのこと
一文字表示
AH = 0x0e
AL = キャラクターコード
BH = 0
BL = カラーコード
戻り値:なし
話を戻し、「 CMP AL,0 CMP AL,0 JE fin」からfinラベルに飛び
fin:
HLT ; 何かあるまでCPUを停止させる
JMP fin ; 無限ループ
HLT命令を実行すると、PC(サーバ)はハードウェア割り込みが検知される(キーボードを押すとか)までの 間スリープに入る模様。
最後に冒頭のORG命令で0x00007c00が指定された意味が語られているが以下の記事が理解できればOKだと思う。
https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%BC%E3%83%88%E3%82%BB%E3%82%AF%E3%82%BF
要するにBIOSの仕様として、「OSは0x7c00にブートすること!」という決まりがあるとの理解でだいたい間違ってなさそう。
より詳しくは、ここのサイトを読むといいかも。
MBRの実行手順だけ、覚えておきたいのでメモ
- BIOSがPOST(Power On Self Test)を実行
- POST後、BIOSはFDD or HDDのMBRを0x7C00にロードし、そこから処理を続行する。(もちろんCD/DVDからブートすることも出来るが、本記事ではFDD/HDDからのブートを扱う。)
- MBRにはOSのカーネルをロードし、実行する為の機械語が格納されており、OSのブートが始まる。
その後はMakefileの話題。
# デフォルト動作
default :
../z_tools/make.exe img
# ファイル生成規則
# ipl.nasとMakefileが存在することを確認後、ipl.nasを元にipl.binとipl.lastを生成する
# ipl.binとMakefileが存在することを確認後、
ipl.bin : ipl.nas Makefile
../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
helloos.img : ipl.bin Makefile
../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek \
wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
# コマンド
asm :
../z_tools/make.exe -r ipl.bin
img :
../z_tools/make.exe -r helloos.img
run :
../z_tools/make.exe img
copy helloos.img ..\z_tools\qemu\fdimage0.bin
../z_tools/make.exe -C ../z_tools/qemu
install :
../z_tools/make.exe img
../z_tools/imgtol.com w a: helloos.img
clean :
-del ipl.bin
-del ipl.lst
src_only :
../z_tools/make.exe clean
-del helloos.img
今まで作っていたバッチファイルが全てMakefileに統合された。素晴らしい!
cleanとかrc_onlyの書き方も参考になる。