Ubuntu 18.04.1 LTSでやる 30日OS本 〜22日目〜
Ubuntu 18.04.1 LTSでやる 30日OS本、22日目です。 他の章へのリンクはここにあります。
1. OSを守ろう
問題なく動作していることが確認できました。
2. バグ発見を手伝おう
QEMUでもbug1.hrb
では「AB」と表示された後に例外が発生しました。EIPレジスタの値を表示させると「EIP = 00000062」となりました。
bug1.map
を見ると、
(前略) .text 0x0000000000000030 0x73 *(.text) .text 0x0000000000000030 0x5d obj/bug1.o 0x0000000000000030 app_main *fill* 0x000000000000008d 0x3 .text 0x0000000000000090 0x13 obj/a_nasm.o 0x0000000000000090 api_putchar 0x000000000000009c api_end (後略)
となっており、app_main
内で例外が発生したことがわかります。
bug1.lst
の生成方法がわからなかったので、詳細はbug1.o
をディスアセンブルすることで確認します。
objdump -M intel -D obj/bug1.o
の結果の一部を下に示します。
00000000 <app_main>: 0: 55 push ebp 1: 89 e5 mov ebp,esp (中略) 2f: 83 c4 10 add esp,0x10 32: c6 45 0f 43 mov BYTE PTR [ebp+0xf],0x43 36: 8a 45 0f mov al,BYTE PTR [ebp+0xf]
この結果と 0x30 + 0x32 = 0x62 より、mov BYTE PTR [ebp+0xf],0x43
で例外が発生していたと特定できました。
なお、'C'
=0x43
です。
ところで割り込みの処理asm_inthndlerXX
は大体どれも同じ処理をしています。同じことを繰り返し書いておくのは嫌なので、NASMのマクロを利用してまとめてしまいました。
NASMのマクロは
%macro [マクロ名] [引数の数] (中身) %endmacro
という形で宣言でき、
[マクロ名] [引数1],[引数2],...,[引数n]
で呼び出せます。マクロの中身にある%1, %2, ..., %n
が対応する番号の引数として展開されます。
3. アプリの強制終了
アプリの実行途中で強制終了できるようになりました。[Shift]+[F1]
ではなく[Break]
で強制終了するようにしようとも思ったのですが、
[Break]
は送られてくるキーコードが長くて面倒だったため、今後の課題とすることにしました。
4.・5. C言語で文字列表示
ここでの説明でリンカスクリプトの中身が解読できます。ESPレジスタの初期値がここでは0x400
となっているので.head
内を書き換え、
下の方にある.data
から始まる部分を.data 0x400: ~~~
に変更します。https://vanya.jp.net/os/haribote.html#gcchrbにあるリンカスクリプトの
アプリケーション用と同様のものに差し替えても良いかも知れません。
ここからAPIを利用して何かをすることが増えるので、api_***
という関数の宣言を書き並べたヘッダファイルapi.h
を作っておくことにしました。
また、"Hari"が見つからないと実行されないようになったため、アセンブラでアプリを作る場合にも一旦オブジェクトファイルを作ってリンクするという流れにします。
Makefile
をこれらに合わせて変更します。
APPS := $(patsubst app/%.c,bin/%.hrb,$(patsubst app/%.asm,bin/%.hrb,$(filter-out app/api.asm app/har.lds app/api.h,$(wildcard app/*.*)))) # あるいは #APPS := $(patsubst app/%.asm,bin/%.hrb,$(filter-out app/api.asm,$(wildcard app/*.asm))) $(patsubst app/%.c,bin/%.hrb,$(wildcard app/*.c)) bin/%.hrb: app/%.c app/api.h obj/api.o app/har.lds Makefile gcc -fno-pie -march=i486 -m32 -masm=intel -nostdlib -c $< -o obj/$(*F).o ld -o $@ obj/$(*F).o obj/api.o -e app_main -Map lst/$(*F).map -m elf_i386 -T app/har.lds bin/%.hrb: app/%.asm obj/api.o app/har.lds Makefile nasm -felf $< -o obj/$(*F).o -l lst/$(*F).lst ld -o $@ obj/$(*F).o obj/api.o -e app_main -Map lst/$(*F).map -m elf_i386 -T app/har.lds obj/api.o: app/api.asm Makefile nasm -felf app/api.asm -o obj/api.o
として、$(APPS)
をイメージファイルの依存関係に書いておけば良いです。なお、エントリポイントは「Harimain」
から「app_main」に変更してあります。api.asm
は本でのa_nask_nas
にあたるファイルです。
このようにしておけば、新しいアプリを作るときにもMakefile
はいじらなくても良くなるはずです。多分。
6.・7.
ウィンドウが増えました。(書いていないので当然)出てきたウィンドウはまだ動かせません。