K氏のheboOSをまねてみる

41:Re: INT 0x09 の乗っ取り
hideyosi 09/28 01:06
嗚呼・・・とうとうKタンが見るに見かねてお答えを・・・
だめだなぁ・・・ヲレ・・・(T∀T)

・・・ってなわけで、ソースを改造。

--------------------------------------------------------
[BITS 16]
[OPTIMIZE 1]
[OPTION 1]
[INSTRSET "8086"]
[FORMAT "BIN"]
ORG 0x100

;表示文字「A」をセット
MOV AL,0x41

;BIOSのキー入力を乗っ取る
MOV AX,0
MOV ES,AX ; ESを0にする。
MOV WORD[ES:0x09*4+0],IINT09
MOV WORD[ES:0x09*4+2],CS
MOV AX,DS
MOV ES,AX ; ESをもとにもどす。

;ループにジャンプ
JMP GULGUL


;キー入力を待つループ
GULGUL:

;ループが廻っているのがわかるようにALレジスタの文字を表示
MOV AH,0x0e
INT 0x10
JMP GULGUL

IINT09:
;ALレジスタの文字を「B」に切り替える
MOV AL,0x42
IRET

EEND:
;一応保険
;MS-DOS終了
INT 0x20
---------------------------------------------------------

コンパイル完了。いけーーー!
・・・・・だめじゃん・・・・ orz ・・・・・・

うーん・・・・。Kタンのソースでもだめってことは・・・・

は!!!!!!!!!



42:Re: INT 0x09 の乗っ取り
I.Tak. 09/28 01:11
>WORDってなんじゃらほい???
アセンブリにはC言語のような型宣言が無いので, メモリに
アクセスするたびに型 (大きさ) を明示するのです。WORDは
2バイトです。

中身に関するツッコミです。
割り込みルーチンに進入するときはレジスタの中身は不定ですし,
どこへ帰るのかも不定なので, 期待どおりには動かないかと
思います。BIOS内部で割り込みに分岐しないという保証はあり
ません。いやむしろ割り込み要因をクリアしてないからint9が
かかった時点でおかしくなるんじゃないかな? 詳しくは分かり
ませんが。

しっかし……イキナリ割り込みプログラミングとはチャレンジャー
ですなあ。hideyOSiを作っているというのを初めて見たときは
テキストVRAMをいじるあたりからやるのかと思っていました
(←意味無くBIOSを避ける思考)。


43:Re: INT 0x09 の乗っ取り
hideyosi 09/28 01:12
まてよぉぉぉ?????

このソースだと、最初にALレジスタに表示する文字(A)のコード。0x41を代入している。

でも、そのあと、
MOV AX,0
ってやっている。
・・・ALとかAHって、AXレジスタを割ったやつじゃなかったっけ?
ってことは、この時点ではALも0になっているってことじゃん!!

そんなわけで、

--------------------------------------------------------
[BITS 16]
[OPTIMIZE 1]
[OPTION 1]
[INSTRSET "8086"]
[FORMAT "BIN"]
ORG 0x100

;BIOSのキー入力を乗っ取る
MOV AX,0
MOV ES,AX ; ESを0にする。
MOV WORD[ES:0x09*4+0],IINT09
MOV WORD[ES:0x09*4+2],CS
MOV AX,DS
MOV ES,AX ; ESをもとにもどす。

;表示文字「A」をセット
MOV AL,0x41

;ループにジャンプ
JMP GULGUL


;キー入力を待つループ
GULGUL:

;ループが廻っているのがわかるようにALレジスタの文字を表示
MOV AH,0x0e
INT 0x10
JMP GULGUL

IINT09:
;ALレジスタの文字を「B」に切り替える
MOV AL,0x42
IRET

EEND:
;一応保険
;MS-DOS終了
INT 0x20
---------------------------------------------------------
こんなふうに修正しました。

さてさて。コンパイルして・・・・・
キタ━━━━━━(゜∀゜)━━━━━━!!!!!!!!
やったーー! 想定どおりの動作したぞぉぉぉ!!!!!!

また野望に一歩近づいた!!!!!! <アホ

よーし。とりあえず一旦この課題は終了。先に進む前に、Kタンに教えてもらった部分がなにを意味するアセンブラなのか、勉強しないと!


44:Re: INT 0x09 の乗っ取り
-- K 09/28 01:45
よかったー。

I.Tak.さんの懸念はもっともなのですが、この場合はこれでうまくいくはずだと思っておりました。
無事にうまくいって、僕も嬉しいです。あまり突っかかると、naskを疑われる心配が(笑)。
何はともあれ、割り込みの雰囲気がつかめたのはとてもよいと思います。

45:Re: INT 0x09 の乗っ取り
hideyosi 09/30 06:58
おさらい。

--------------------------
;BIOSのキー入力を乗っ取る
MOV AX,0
MOV ES,AX ; ESを0にする。
MOV WORD[ES:0x09*4+0],IINT09
MOV WORD[ES:0x09*4+2],CS
MOV AX,DS
MOV ES,AX ; ESをもとにもどす。
-------------------------------

MOV AX,0
これはまあ解る。AXレジスタ(16ビット)に、0を代入。AXレジスタは、0x0000という状態になる。

MOV ES,AX ; ESを0にする。
???なんでこんなことするの?ESに直接0を代入できないの?
実験してみたら、できなかった。ESレジスタには、直接数字を代入することはできないようだ。だから、ESレジスタに値をセットしたい場合は、AXなどの汎用レジスタに一度代入して、レジスタ間で値をコピーしなくてはいけないようだ。

ESレジスタって、なにするレジスタ? DSレジスタ(データがあるセグメントを管理)の予備的なレジスタ??


MOV WORD[ES:0x09*4+0],IINT09
うーん。ここいらへんがわからんなぁ・・・なになに?「WORD」は、2バイトをあらわす符号!?
ここの処理を分解して考えてみる。つまり、
WORD[ES:0x09*4+0]というところに、IINT09(ラベル。多分実態はメモリアドレス)を代入している。
ここは、そもそもはINT09の割り込みがあった場合のジャンプ先のアドレスを書き換えるための処理。で、+0だから、ここは「オフセット値」が入るはず。

うむむむ!??? (くわーーー!むず〜!!)



46:Re: INT 0x09 の乗っ取り
feel 10/02 02:48
おお、頑張ってますねぇ流石です

CSがコードセグメント
DS,ESがデータセグメント(FS,GSは8086には含まれなかったような)
SSがスタックセグメント
でしたね

CSは今実行しているコードのアドレス
DS,ESは実行しているコードがメモリにアクセスするときに参照するアドレス
SSはPUSH等の命令のときに格納、参照するやつ
という感じだったと思います

MOV命令は
汎用レジスタには汎用レジスタとオフセットアドレスと即値
セグメントレジスタには汎用レジスタやラベルとかで即値は入らないとのことです

って、何だこの時間は!

47:Re: INT 0x09 の乗っ取り
hideyosi 10/02 13:16
feelさんドモです〜。

>CSがコードセグメント
>CSは今実行しているコードのアドレス

おぉ! 解ってきたぞ!!(feelさ、感謝)

MOV WORD[ES:0x09*4+0],IINT09
MOV WORD[ES:0x09*4+2],CS

割り込みが発生した場合のジャンプ先の情報が明記されている場所。これが割り込みベクタテーブル。(ま、よーするに、「割り込み先一覧表」ってとこね。)

で、ベクタテーブルは、割り込み番号順に、「ジャンプ先のオフセット値」と「ジャンプ先のセグメント」が書かれているわけ。

(仮にだけど、64KBしか扱わない。あるいは、32ビットとかだと、こんな面倒くさいことはしていないはず。単純に、割り込みが来たら、xxxxxxxx番地にジャンプ! みたいに、一発で解るように書いてあるはず。)

私の例のプログラムの場合、DOSでも動くようになっているプログラム。すなわち、セグメントが割り当てられているプログラム。(えーっと、MS-DOSの場合は、必ず0x100になるんだっけ?)

その内部で、サブルーチン(IINT09)を定義してある。このサブルーチンのラベルは、実際にはコンパイラがアドレスに変換するものなのだろう。

このアドレスを、ベクターテーブルに書き込む方法。それが

MOV WORD[ES:0x09*4+0],IINT09
MOV WORD[ES:0x09*4+2],CS

となるわけか。

一行目。これが、オフセット値を設定している。
で、二行目。ここに、セグメント番地を書き込む。
しかし、MS-DOSだからといって0x100とは限らないかもしれない。(仮に、MS-DOSが、いかなるプログラムでも必ず0x100セグメントで実行する!とか決まっていれば、決め打ちで書き込んでもまあ、いいかもしれないけど。)

いま動いているプログラム(IINT09のアドレスも含めて)の正確なセグメント値は、CSレジスタに保存されている。だから、CSの値を WORD[ES:0x09*4+2] 番地に書き込んでいるわけか。

なるほど!!


48:feelさんへ
hideyosi 10/02 13:48
>>feel氏

あ、そうそう。個人連絡的で恐縮ですが。

feelさんって、以前、ブートローダーを試作なさいましたよね?
もう引っ込めてしまわれたようですが、もし(ほんとにもし)よろしければ、
私に見せて頂くことはできませんか?勉強させていただきたいのですが。
トップページに書いてありますが、当サイトのディフォルトライセンスはKL-01です。これに準拠したくない場合は、明記いだだければ。
(もちろん、「お前さんには見せてあげるが、公開しちゃダメ!」ってのも、ありです。いずれにしても、原作者であるfeelさんの意向に全面的に従いますので)

是非、ご検討いただけましたら幸いです。


49:Re: feelさんへ
YARMA 10/02 18:37
僕が答えていいのか分かりませんが(ていうか、いかんだろ)、とりあえず。

http://jp.y42.briefcase.yahoo.co.jp/bc/thebblos/lst?.di
r=/%cb%dc%c2%ce/%a5%d6%a1%bc%a5%c8%a5%ed%a1%bc%a5%c0&.vi
ew=l&.src=bc&.done=http%3a//jp.y42.briefcase.yahoo.co.j
p/bc/thebblos/lst%3f.dir=/%25cb%25dc%25c2%25ce%26.src=b
c%26.view=l

Wikiから移動したやつがぁ・・・まだ残ってた。
消すのを希望するならMAILなどで連絡してください。
(Feelさんのメールアドレス知らなかった・・・orz
てなわけで、ここにいそうだから一応(でも、やっぱりだめかな、ここでいうの。

50:Re: feelさんへ
feel 10/02 18:51
公開するのは全然構いません
見難い点がかなりありますが
ここにソース載せたほうがいいですかね?
それともリンクがいいですか?
もしくは、sutekata@yahoo.co.jpにでも連絡を
>>YARMA
消す、消さないはあなたの判断に任せます
それよりも新しいのが出来ているのでね

1-

BluesBB ©Sting_Band