セキュリティ

『30日でできる! OS自作入門』のNASKを汎用アセンブラでかきなおす

今回は、好きな文字列を画面に出力するだけのOSをアセンブラで作ります。
今回まとめるのは、1日目の後半から3日目の前半くらいまでです。

こちらの記事の続きです→プログラミングを基礎から学ぶならOSを作るべし??ー1日目ー

さて、今回ですが、使用するアセンブラはNASMというフリーのアセンブラです。
16ビット、32ビット (IA-32)、64ビットすべてのコード生成に対応しています。

下の参考書籍では、著者のオリジナルのアセンブラであるNASKが利用されていましたが、応用がしづらい点や内部の仕様が非公開のために、NASMで書き直しました。

プログラミングの基礎からはじめて、30日後にはウィンドウシステムを有する32bitマルチタスクOSをフルスクラッチで作り上げるという入門書。

もくじ

  1. 今回のゴール
  2. アセンブラ言語NASMとは
  3. NASMで書く
  4. コードについて
  5. まとめ
  6. 参考

今回のゴール

今回のゴールはこちら。

前回と同じく、画面に文字列を表示させるだけのイメージファイルですが、"Hello, World"以外の文字列が表示されています。
前回のようですべて機械語で書くと、表示させる文字列の変更は少し大変になりますが、今回はアセンブラになったことで、表示させる文字列を簡単に変更できるようになりました。

アセンブラ言語NASMとは

まず、今回使用したアセンブラであるNASMについて紹介していきます。

アセンブラとは、機械語にニーモニックと呼ばれる名前をつけ、プログラミングする手法のことです。

機械語は本来0と1の数字の羅列なので人間にはほとんど理解できませんが、アセンブラとすることで人間にとっても理解しやすくなるのです。

ちなみに、アセンブラはIPAの基本情報技術者試験のプログラミング問題としても出題されています。

基本情報アセンブラを最速最短で突破するための勉強法

NASMは、BSDライセンスのオープンソースによって提供されるアセンブラです。
インテルx86を対象としており、16ビット、32ビット (IA-32)、64ビットすべてのコード生成に対応しています。

BSDライセンスとは
「無保証」であることの明記と著作権およびライセンス条文自身の表示を再頒布の条件とするライセンス規定である。
この条件さえ満たせば、BSDライセンスのソースコードを複製・改変して作成したオブジェクトコードをソースコードを公開せずに頒布できる。

BSDライセンス

また、NASMは『プログラマが簡単に理解できるインテルアセンブリ言語として親しまれるようにする』という思想のもと設定されています。

今回は、そんなNASMを使っていきます。

NASMで書く

さて、今回参考書籍である『30日でできる! OS自作入門』のコードをNASM用に書き変えたものは下記のとおりです。

下記のアセンブラをコンパイルすることで、前回記事と同じようなイメージファイルが生成されるのです。

  ipl10.asm
  ; hello-os
  ; TAB=4
      CYLS EQU 10
  		ORG		0x7c00			; このプログラムがどこに読み込まれるのか

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

  		JMP SHORT entry
  		DB		0x90
  		DB		"HELLOIPL"		; ブートセクタの名前を自由に書いてよい(8バイト)
  		DW		512				; 1セクタの大きさ(512にしなければいけない)
  		DB		1				; クラスタの大きさ(1セクタにしなければいけない)
  		DW		1				; FATがどこから始まるか(普通は1セクタ目からにする)
  		DB		2				; FATの個数(2にしなければいけない)
  		DW		224				; ルートディレクトリ領域の大きさ(普通は224エントリにする)
  		DW		2880			; このドライブの大きさ(2880セクタにしなければいけない)
  		DB		0xf0			; メディアのタイプ(0xf0にしなければいけない)
  		DW		9				; FAT領域の長さ(9セクタにしなければいけない)
  		DW		18				; 1トラックにいくつのセクタがあるか(18にしなければいけない)
  		DW		2				; ヘッドの数(2にしなければいけない)
  		DD		0				; パーティションを使ってないのでここは必ず0
  		DD		2880			; このドライブ大きさをもう一度書く
  		DB		0,0,0x29		; よくわからないけどこの値にしておくといいらしい
  		DD		0xffffffff		; たぶんボリュームシリアル番号
  		DB		"HELLO-OS   "	; ディスクの名前(11バイト)
  		DB		"FAT12   "		; フォーマットの名前(8バイト)
  		TIMES   18 DB 0				; とりあえず18バイトあけておく

  ; プログラム本体

  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				; 無限ループ

  msg:
  		DB		0x0a, 0x0a		; 改行を2つ
  		DB		"My OS!"
  		DB		0x0a			; 改行
  		DB		0

  		TIMES   0x1fe-($-$) DB 0		; 0x7dfeまでを0x00で埋める命令

  		DB		0x55, 0xaa

  ; 以下はブートセクタ以外の部分の記述

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

コードについて

簡単にアセンブラの中身を見ていきます。

まず、頻出している"DB"とは、"Data Byte"を意味します。
1バイトごとに格納されるデータを直接記載しているわけですね。

中々興味深いです。

"ORG"は、プログラムが読み込まれる際の先頭アドレス、"JMP"はC言語のGOTOのような意味を持ちます。

今回は、最終的に呼び出されて出力されるmsgの部分を書き換えることで、表示される文字列を自由に設定することができます。

ちなみに、コンパイルするためには以下のツールが必要になります。

・NASM
・QEMU(要X環境)

Ubuntu環境であれば、次のコマンドでインストール可能です。

  sudo apt install nasm qemu

また、コンパイルは下記のコマンドで実行できます。

  nasm -f bin <.asmファイル名> -o <出力ファイル名>

まとめ

今回は『30日でできる! OS自作入門』の2日目までの内容をまとめました。

せっかくなら汎用アセンブラでやりたいと思ってしまったせいで随分と時間がかかりましたが、かなり勉強になりました。

どのみち僕のOS開発のゴールはラズパイで動くOSの開発ですし、その時に汎用アセンブラを使うことになると思うのでちょうどよかったかなと思います。

OS開発は、普段意識しない低レイヤの仕組みをがっつり扱うので、非常に面白いですね。

ぜひ、皆さんもチャレンジしてみてください。

プログラミングの基礎からはじめて、30日後にはウィンドウシステムを有する32bitマルチタスクOSをフルスクラッチで作り上げるという入門書。

参考

プログラミングを基礎から学ぶならOSを作るべし??ー1日目ー

BSDライセンス

naskについてのページ

1.NASK環境からの解脱

NASM - The Netwide Assembler

COMMENT

メールアドレスが公開されることはありません。