K氏のheboOSをまねてみる |
1 名前:hideyosi 2004/9/22 17:32
OSASKのK(川合氏)が、OS作成に関するチュートリアルを公開している。ふむふむ。なになに?
あいかわらずKは口がうまい!
なんだか出来そうな気がしてくるじゃねーかよ! そんなわけで、思いつくまま体験をばしてみたり。
参考: http://community.osdev.info/index.php?FirstStep
|
2 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 17:45
さーって。まずはDOSのプログラムでいいんだよね。
・・・があぁぁあ!!
私って、そいえばDOSのプログラムもしたことないんだよね。(^^;)
とりあえず、昔つかったMinGWがセットアップされたまんまだ。これ使えるのかな???
|
3 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 18:17
MinGWでできるようだね。MinGWをインスコして、コマンドプロンプトでパスを通すだけ。
お決まりのHello Worldだよん。(いちおう区別できるように、名前とか書いてみたり。)
#include<stdio.h>
int main(){ printf("Hello World by hideyosi\n"); }
おー! めでたくa.exeが出来上がったニョ!
(なんか幼稚なことしてますねぇ・・・(^^;) )
|
4 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 18:31
さーて。こっからが大変。
MinGWを使って、DOSのシステムコールを使わないようにプログラムするにはどうしたらいいのかな?
(なんか確かにアセンブラ使ったほうがいいのかもしんないけどね。ちょっとがんばって調べてみよう。)
|
5 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 19:51
・・・うーむ・・・ どうもあっちこっちで調べてみたんだけど、C言語の中にアセンブラを自然に埋め込む「インラインアセンブラ」っつー機能を使うみたいだなぁ。
・・・あれ?そうすると、やっぱアセンブラがまったくわかんないとアカンつーことかな??? (^^;)
どうせ最初はHelloWorldをOSみたく起動させようってだけなんだし、しゃーない。ちょこっとアセンブラの解説を読んでみよう。
|
6 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 20:15
のわぁぁん!!! MinGW(GCC)って、インラインアセンブラが高機能なぶん、エラクややっこしいじゃんか! でもなぁ。アセンブラってややこしいから最低限に収めて、あとは御気楽なCとかでっていうのには、素のアセンブラは・・・ えーい!メンドイ!! とりあえずテケトーに文字だけ出すアセンブラのコード書いちゃえ!
|
7 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 21:06
・・・つかさ。NASKがあるじゃんか!! ぐはぁ! Kタンのサンプルまであるじゃんかよ!!! そんなわけで、まずはNASKでさっきのCと同じようなのを作ろう。
[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 MOV DX,msg MOV AH,0x09 INT 0x21 MOV AX,0x4c00 INT 0x21 msg DB "hello, world by hideyosi", 0x0d, 0x0a, "$"
えーっと。こんなんでnaskでコンパイルしてと。 あっれ? ぜんぜん出力しないぞ!? と頭を抱えていたんだけど、ふと思い立って、純粋DOS(95)で実行。うにょ! 動いた!
バンザーイバンザーイ!!!!!!!
・・・ だめじゃん!!!! orz
だーかーらぁ!!! INT21とか使っちゃいけないんだってば!! うーん。やっぱ486本読まんとイケンかな?? (T∀T)
|
8 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 22:45
うーん。ちょこっと解ってきたぞ。えーっと。AT互換機の場合、BIOSに様々な実行命令があらかじめ格納されている。そこに命令するとその動作をしてくれるってわけだ。すんごく大雑把ではあるけど、DOSのファンクションコールやVBの関数と理屈が同じわけだ。
で、どうもある程度、パターンがあるみたいだ。DOSのファンクションコールは ahレジスタに呼び出したい機能の番号(ファンクション番号)を入れて INT 21 とやると、その機能が働く。 BIOSの場合は、どうもahレジスタに機能番号を設定して INT 10 とやるみたいだ。(もちろん例外とかオプションもあるけどね)
BIOSの機能番号で「文字表示」は、0eらしい。で、この機能は他のレジスタを使ってオプションを設定するわけか。
AL:表示する文字の16進コード
えーっと。するってーと、たとえば画面にAって表示するだけの場合だと、
mov al,0x41 ;「A」のアスキーコードは41hだよな。たしか mov ax,0x0e INT 0x10
っと、こういうことになるのかな?? (実験してみよう)
|
9 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/22 23:31
そんなわけで、こんなソースを作って実験。
[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100
MOV AL,0x41 MOV AH,0x0e INT 0x10 JMP $
マシンをリセットして・・・・ キタ━━━━━━(゜∀゜)━━━━━━!!!!!!!! へぇぇ! おもしれー! なるほどなるほどぉ!!! もっといろいろなBIOSコールがあるみたい。やってみよ!
|
10 Re: K氏のheboOSをまねてみる
名前: -- K 2004/9/22 23:32
MinGWで書いていた頃は、 「それじゃそもそもIA-16じゃなくてIA-32・・・」 とか思って心配したのですが、 なにやら毎度のガッツで元気に乗り切っている。 実に楽しみです。
|
11 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/23 1:12
さーて! そんなわけで、BIOSだけで文字を表示することができました。こんなコードね。(^^;)
[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100
;画面クリア ;カーソルを0,0に設置して MOV BH,0 MOV DH,0 MOV DL,0 MOV AH,0x02 INT 0x10
;全画面消去(80文字24行) MOV AL,0 MOV BH,0 MOV CH,0 MOV CL,0 MOV DH,24 MOV DL,80 MOV AH,0x06 INT 0x10
;文字列の表示 MOV AL,0x01 MOV BH,0 MOV BL,0x0F MOV CX,30 MOV DL,0 MOV DH,0 MOV ES:BP,msg MOV AH,0x13 INT 0x10
MOV DL,0 MOV DH,1 MOV ES:BP,msg2 INT 0x10
MOV DL,0 MOV DH,2 MOV ES:BP,msg3 INT 0x10
MOV DL,0 MOV DH,3 MOV ES:BP,msg INT 0x10 JMP $
;メッセージ部分 msg DB "******************************" msg2 DB "* Kokoga Henndayo! *" msg3 DB "* The-BBL!!! *"
動作も無事、DOSで確認。ちゃんと動いてる。 ほいだばほいだば!!! さっそくこれをOSみたく、起動時に読み込むようにしてみましょ。 そのためにはIPLっつーもんを書かなくちゃいけない。
・・・・ギブアップ!!!! (;´д`) (つか、あとで勉強しまする・・・)
heboOSに付いていたipl.binをそのまんま流用。なになに? copyコマンドで繋ぐ!??
えーっと。こーゆーことかな???
>copy ipl.bin+test2.com test2.bin
おぉ! 一個になったぞ!!!!
えーっと。そんでもってimgtolでFDに書き込むわけね。
>imgtol w a: test2.bin
そんで出来上がったFDを入れてリセットしてと・・・・ キタ━━━━━━(゜∀゜)━━━━━━!!!!!!!! ぶははははは!!!! でけたでけたーー!!!!! (爆
|
12 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/23 2:58
xxビットCPUの意味。
CPUについて調べてみた。・・・・ギブアップ!!!! (;´д`) いろいろややこし過ぎてわからんわい!!!!
だた、私お得意の「一旦大雑把な法則を見つけ出して憶えていく」に照らし合わせると・・・
xxビットCPU。つまり二つの要素に影響する。メモリアクセスと演算処理。
まずは演算処理。 「ビット」って言うとピンとこないので、ソロバン、もしくは電卓を想像してほしい。8ビットは、桁が8桁までしかない電卓と考える。 例えば8ビットCPU。8ビット。すなわち桁が8桁(零から千万まで)しかない電卓。0〜99,999,999までに収まるような計算(計算結果も含めて!)なら、一発で求められる。「=」を押せば、答えは液晶に表示される。 しかし、それを超えると面倒(時間が掛かる)になる。これは想像できるだろう。一旦、メモに書いたりして、桁を分割したりして計算しないと答えがでない。つまり、何倍も時間が掛かるわけ。 つまり、平べったい理屈で言えば、電卓の桁数(ビット)が多ければ多いほど、一回の計算で済む。すなわち、早いということになる。
次に、メモリアクセス。 アドレス空間が・・・っていうとピンとこないので、「使えるメモ帳のページ数」と考える。 ここで言うメモ帳はへんな性質があって、さっきの電卓の桁数に応じて、ページ数・一ページに書ける桁数が決まる。 つまり、8ビット(8桁の電卓)だと、メモ帳のページ数は0〜99,999,999ページまでしか使えない。さらに、一ページに書き込める数字も、0〜99,999,999に限定される。 この範囲に収まる計算ならよいが、桁があふれると、とたんに何倍もの計算時間が掛かるってのは、もうわかるよね。
8ビット、16ビット、32ビット。これだけ見れば、「たかが倍じゃん。たいして違わないんじゃないの?」と思うかもしれないけど、上記の例で比べればピンと来るでしょ?つまり、
8ビット(8桁電卓) ・一回で0〜99,999,999までしか計算できない ・メモ帳のページ数は9千万まで ・一ページに書ける最大の数字は99,999,999
16ビット(16桁電卓) ・一回で0〜9,999,999,999,999,999までの計算が出来る ・メモ帳のページは、9千兆以上! ・一ページに書ける最大の数字も9千兆以上!
これを考えれば、例えばもっともよく使う数字の桁が十億あたりだった場合、8桁と16桁では、倍ではすまない。ヘタすると何十倍も時間の差が出る。
だから、通常、ビットが多いと、それだけ早くて高性能ってことになるわけ。
(余談だが、「じゃ、ちょうどいい12桁の電卓作ればいいじゃん!」って意見がある。ごもっとも!でも、この電卓はなぜか倍というキリのいい数字でないとかえって作るのが大変という性質を持っていると考えてもらえば。)
・・・しかし、「じゃ、ビット(電卓の桁)が多ければ多いほどいいのか!」っていうと、そうでもないんだよね。これが! (^^)
今の物価を考えると、ウン十億まで(10桁)があれば十分でしょ?普通。 (私は7桁でジューブンだ!悪かったな!!!) そうなると、液晶の桁が10個並んでいる電卓で十分だよね?。そんな世の中で、全ての電卓が、16桁あったら・・・邪魔!!!! 「今の」物価で考えれば、8桁の電卓で十分だし、小さいので扱いや持ち運びも便利。16桁の電卓は「過剰品質」ってことになるわけ。 でも、例えば10年後。またバブル景気があって、給料の平均が一億円。そのぶん、缶コーヒーが一本12万6千900円という世の中になったとしよう。そうすると、8桁電卓は「すさまじく不便」になり、多少大きくても16桁の電卓が一番便利になる。
つまり、その世の中や対象によって、一番使いやすくて便利な桁数が変わるということになるわけ。
だから、例えばライブドアの社長が便利なパソコンは64ビット。でも、私が使いやすいのは8ビット。とか、そういうふうになるわけ。 (これは電卓の例での話ね)
現在、一番使いやすいとされているのが、32ビット。もう既に64ビットのCPUはあるんだけど、ちょーっと過剰品質状態なわけ。 (でも、じりじりと「32ビットじゃ足りない!」という状況が増えてきているのね。)
|
13 Re: K氏のheboOSをまねてみる
名前: -- K 2004/9/23 8:28
あとからここを読む人のためにちょっとフォロー
MOV ES:BP,msg
はたまたまうまくいっていますが、本来は正しくない表記です。
ES:BP == msgのアドレス
といった場合、msgのアドレスのオフセットをBPに、セグメントをESに入れます。 でも、残念ながらESとBPに値を代入するのは、1個のMOV命令ではできません。これはCPUの仕様です。
.COMファイルの場合、とりあえずESには適切な値が入っていますので、ESへの代入は気にしなくていいでしょう。ということで、
MOV BP,msg
がこの場合の正しい記述になります。
|
14 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/23 17:55
CPUのオベンキョ。 リアルモードとプロテクトモード。 (例によって大雑把だよ)
インテルのCPUは、幸か不幸か、8086という16ビット版のCPUが大ヒットした。そして、その上で動くことを前提にしたMS-DOSも大ヒット。沢山の資産が生まれた。
時代が進み、16ビットじゃ足りないってことで、インテルは32ビットの高機能な新型CPU、80386を開発!。これで今までの面倒な問題も一気に解決。高速・大容量のメモリも使える。ばんざーい!
・・・と思ったら、あまりにもMS-DOSがヒットしすぎていた。いまさらMS-DOSがまったく動かないCPUじゃ売れない。MS-DOSの32ビット版を作ったって、みんながその新MS-DOSを買って使ってくれるとは限らない。こまった・・・
で、しょうがない。せっかくの32ビットだけど、16ビット(8086)とまったく同じに動く機能を追加しよう。これなら古いMS-DOSしか使いたくない人にも安心して買ってもらえるぞ!
うーん。いろいろとリサーチしたら、なんかみんなMS-DOS以外、あんまし使いたがっていないようだ。32ビットのまんまだと、「動かねーじゃねーか!」とか苦情きそう・・・
じゃ、こうしよう。80386は本来は32ビットだけど、電源を入れた瞬間は8086ってことで動く。で、プログラムとかである特別なスイッチを入れれば、32ビットに切り替わるというように設計する。
・・・っとまあ、こういう感じだったようです。(本当の経緯は違いますよ!念のため)
で、その、電源を入れたばっかりの状態(8086として動く、16ビットの状態)、これを、「リアルモード」といい、なんらかの方法でスイッチが入れられ、32ビットになった状態を、「プロテクトモード」と言うわけ。
この、80386で定められた動作の規格は、今でもずーっと受け継がれている。80486・80586(Pentium)・80686(Pentium2)・・・・
OSはいろいろあるけど、インテルのCPUで動くものは、みなこの仕様(というか、制約?)に縛られる。なので、動作までは、
1、電源投入 2、いやおうなしに、CPUは8086(リアルモード)になる。 3、CPUの仕様として、決まった番地のアドレスにジャンプして実行する 4、この決まった場所は普通、ROMになっている。ここにBIOSというプログラムが書いてあって、これを実行する。(BIOSが壊れているとかでない限り、これは回避できない) 5、BIOSには、FDのある部分を読んできて実行しろというプログラムが書かれている。(これがIPL) 6、IPLが実行される。(へ理屈だが、このIPLに全ての命令を書き込むことが出来れば、この時点でOSということになる。IPLには大きさの制限があるので、普通はここには、xxxを読み込んで実行しろという程度の命令だけしか書かれていない) 7、IPLによって、OSの本体が読み込まれ、実行される。(OSが起動!) 8、この時点では、どんなOSでも16ビット。MS-DOSと大差なく、低性能。 9、LinuxやOSASKなどの32ビットOSの場合は、この16ビットの状態の時に、あるスイッチを入れて32ビット状態(プロテクトモード)に切り替えられる。 10、ここで初めて、マシンは32ビットになる。あとは、16ビットの時にあらかじめ読み込んでおいた32ビットでプログラムが書かれている場所にジャンプし、それを32ビットのCPUとして実行を開始する。 11、32ビットOS、起動・初期化処理開始!!!!
・・・っとまあ、大変大雑把だがこんな感じなのだろうなぁ。きっと。
|
15 Re: K氏のheboOSをまねてみる
名前: -- K 2004/9/23 18:56
> ・・・っとまあ、大変大雑把だがこんな感じなのだろうなぁ。きっと。
まさにこんな感じです。あまりにも正確すぎて、フォローするところがありません(笑)。
|
16 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/24 3:46
ずーーーーっとOSの骨組(というか概念)を調べていたら、こんな時間かよ!!!! (;´д`) ヲレ、明日仕事なんでツけど・・・(つか、既に「今日」じゃん!)
Linuxのカーネル(の解説書)を読んでました。もう、なにがなんだかサパーリなんだけど、一つ、「もしかして、これか?」なのを見つけました。
・・・無限ループ・・・
_人人人人人人人人人人人人人人_ > な なんだってー!! < ‾^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^‾ _,,.-‐-..,,_ _,,..--v--..,_ / `''.v'ν Σ´ `、_,.-'""`´""ヽ i' /‾""''--i 7 | ,.イi,i,i,、 、,、 Σ ヽ . !ヘ /‐- 、u. |' |ノ-、 ' ` `,_` | /i'i^iヘ、 ,、、 | |'' !゛ i.oニ'ー'〈ュニ! iiヽ~oj.`'<_o.7 !'.__ ' ' ``_,,....、 .| . ,`| u ..ゝ! ‖ .j (} 'o〉 `''o'ヽ |',`i _,,..-<:::::\ (二> / ! _`-っ / | 7 ‾ u |i'/ . |、 \:::::\ '' / \ '' /〃.ヽ `''⊃ , 'v>、 !、\ \. ,‾ γ/|‾ 〃 \二-‐' //`
|
17 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/24 3:58
MS-DOS(いやまあ、どんなOSも厳密にはそうだけど)は、起動して、必要な処理を全て終えると、プロンプト(命令の受付準備が完了しました。嗚呼・・・ご主人様。なんでもお命じください・・・)を出して、止まっちゃう。ほっとくと、ずーーーっと命令を待っている。そう。ずーーーと!!!
これって、「無限ループ」なんじゃないのかなぁ。
そんで、その無限ループの途中に、もしなんらかの命令があったらそれを実行し、実行が終わったら、また元のループに戻ってきて、またずーーーっと命令が来るまで無限ループをしてずーっと待っていると・・・
こんな感じ・・・・か?
↓ 初期化とかの処理 ↓ ↓ スタート地点 ←←←←←←←←← ↓ ↑ ↓ ↑ ↓ ↑ もし、キーボードが押されたら、 (グルグル・・) 「尿!」と表示して戻って来い ↑ ↓ ↑ ↓ ↑ ↓ ↑ スタート地点に戻れ!→→→→→
こういう理屈・・・なのかなぁ。
|
18 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/24 4:00
つーか、寝ろよ!!! 俺!!!! (;´д`)
|
19 Re: K氏のheboOSをまねてみる
名前:あっきぃ 2004/9/25 16:37
Site
hideyosiさん、こんにちわん。 hideyOSを作っているとKタンからきいてきましたょ! 参考になるかわかりませんが、Mt.orzOSはオープンソースなので よかったらみてみてください〜^^ (…といっても、同じくheboOSの発展版ですが^^;;;)
|
20 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/25 16:56
>>19 にょにょ〜!!! あっきーさ、どもども〜。ありがとう。
さっそくパクッて自分の手柄に ←間違い!
さっそく参考にさせてもらいます〜。 いやいやいや、「heboの発展」とな? まさにいまの私にとっては ドンピシャな資料かもしれない!! うれしー!
ちなみに・・・ >hideyOSを作っているとKタンからきいてきましたょ! それは間違いです!!!! こんなので「OS作っている!」って言ったら、2chでゴルァゴルァと袋叩きにされますって!!
それと、どこまで出来るかわかんないけど、例のTHE-BBLがちゃんとしたライセンスなり方針を決定して、そのライセンスに納得できれば、THE-BBLプロジェクトにブン投げる予定のもんです。 (イラネー!って言われる公算大でつが・・・・ )
|
21 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/25 17:12
・・・あっれ? くそ!
ループって、こういうのじゃないのかなぁ・・・
--------------------------------------- JMP START
START: ;文字の表示 MOV AL,0x41 MOV AH,0x0e INT 0x10
JMP START ---------------------------------------
なんか、レベルの指定の文字がまずいらしいな。ここでエラーが出ている・・・・
|
22 Re: K氏のheboOSをまねてみる
名前:feel 2004/9/25 20:43
頑張れhideyosi氏 私も自分なりに頑張るよ
--------------------------------------- JMP START
START: ;文字の表示 MOV AL,0x41 MOV AH,0x0e INT 0x10
JMP START --------------------------------------- nasmだとうまくいきました (もちろん--------の部分消して)
|
23 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/25 21:08
feelさんドモです〜(始めまして。)
>頑張れhideyosi氏 ありがとうございます〜。がんばります。
>私も自分なりに頑張るよ やっぱそれが一番大事ですよね。ちなみにあくまでもここはコミュニティなので、気がむいたりおもしろそうだったら、気軽〜に無責任〜に遊んでいってくださいね。
|
24 Re: K氏のheboOSをまねてみる
名前: -- K 2004/9/25 23:42
レベル指定って何のことだろうと思ったら、ラベル指定か。
でもおかしいところはなさそうに見えるんですがねえ・・・。 naskでも問題なく動きそうに思うのですが、どうしてだめなんでしょう。
|
25 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/26 9:11
っはっはぁ〜・・・・・ なるほど。「割り込み」ね? これか・・・
つまり、たとえば私自身はこういうプログラムだけを書いたとしても・・
↓ 初期化とかの処理 ↓ ↓ スタート地点 ←←←←←←←←← ↓ ↑ ↓ ↑ ↓ ↑ ↓ (グルグル・・) ↓ ↑ ↓ ↑ ↓ ↑ ↓ ↑ スタート地点に戻れ!→→→→→
実際には、「割り込み」という機能が働いているので、実行時には 私がイヤでもこういう状態で実行されるのか。
↓ 初期化とかの処理 ↓ ↓ スタート地点 ←←←←←←←←← ↓ ↑ キーボードが押されたらxxへ ↑ ↓ ↑ 時計が1秒進んだらxxへ (グルグル・・) ↓ ↑ 牛が鳴いたらxxへ ↑ ↓ ↑ ↓ ↑ スタート地点に戻れ!→→→→→
で、この「xx」の部分を書き換えて、かつそこになにか命令を書いておくと、反応すると・・・・
(・・・つーことは、極論だけど、xxの部分に「なにもするな!」っていう命令を書いておくと、割り込みが効かないという状態に出来る・・・のかな???)
|
26 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/26 10:30
「割り込み」には、ハードウェア割り込みとソフトウェア割り込みがあると。
たとえば、キーボードが押されると、割り込みが発生する。 (つまり、私がなんにもプログラムしていなくても、INT 0x09 が実行される)
私のコレまでのプログラムでは、キーボード押してもなーんにも起きない。これは、INT 0x09 が実行されてはいるが、ジャンプした先になんにも命令が書かれていないからそのまま戻ってくる。
割り込み番号 09番が発生した時の処理って、どこにどうやって書くのかぁ・・・
|
27 Re: K氏のheboOSをまねてみる
名前:feel 2004/9/26 13:20
割り込みをさせない命令といえばCLIですね 許可させるのはSTI で、私的割り込みの解釈 IDTにxxhはここのアドレス、yyhはここのアドレスという情報を書いておき xxhの割り込みが発生するとそこのアドレスを参照、実行 命令はpushしてpopしてiretする(なんだかなぁ・・・) という感じだと思っています 間違っていたらご指摘を
|
28 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/26 15:51
うーーーん。むずかしいなぁ・・・・ えーっと。どの割り込みが発生したのか? これが割り込む番号。キーボードだと9番。 で、もし9番の割り込むが発生したら、xxxへジャンプしろ!と記憶してる部分が割り込みベクタテーブルか。
で、IDTってのはCPU内にある特別なレジスタ。(・・・どこにあるんだろう?)このレジスタに、どこに割り込みベクタテーブルがあるのかを設定するわけか。なになに?LIDT命令??
|
29 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/26 16:02
あーれ? おっかしいなぁ。 NASKでとりあえずいい加減なところに LIDT 0x100 とか書いてコンパイルだけしてみたんだけど、センタックスエラーだ。こんな命令はない?それとも指定が違うのかな?
|
30 Re: K氏のheboOSをまねてみる
名前:feel 2004/9/26 17:23
LIDTは リミット値と先頭アドレスを指定したと思います 例えば
lidt[idtr]
idtr dw 0;リミット dw 0;先頭アドレス
こんな感じではないでしょうか 自信あまりないですが
|
31 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/9/26 17:31
くっそぉ〜!!! LIDTがわからん。(もしかしてNASKでは使えない?) あかん。仕事の時間じゃ!
feelさん、アドヴァイスどうもありがとうです〜
|
32 INT 0x09 の乗っ取り
名前: -- K 2004/9/26 17:48
もちろんLIDTはnaskでも使えます。使えますが、それではおそらくhideyosiさんのやりたいことを達成できないと思うので、簡単に説明します。
とりあえずIDTのことは忘れていいです。
もしINT 0x09を(BIOSから)乗っ取りたいのなら、INT 0x09が来たときに実行してほしいプログラムをどこかに書いて、
(例)
int09: ごにょ
そんでもって、
MOV WORD [0x09*4+0],int09 MOV WORD [0x09*4+2],0
とすればいいです。他の割り込み番号であれば、0x09の部分を変えればOKです。最小値は0x00で最大値は0xffになります。 最小値のとき、アドレスを電卓で計算すると、0x0000と0x0002になります。最大のとき、アドレスを電卓で計算すると、0x03fcと0x03feになります。・・・ということで、割り込み関係の設定は全部で0x0000から0x03ffというわけですが、これは、
http://community.osdev.info/index.php?(AT)memorymap
の「ソフトウェア的用途区分」にも書いてあるわけです。
ちなみに、[0x09*4+0]や[0x09*4+2]に書いてある値を調べれば、いつでも割り込みが起きたときにどういう処理をしているのかが調べられます(もちろんそのアドレスにかかれているプログラムを解析すれば、という意味です)。
めでたしめでたし。
|
33 Re: INT 0x09 の乗っ取り
名前:feel 2004/9/26 18:49
なるほど 自分もあまり割り込みについて・・・なところが多かったので 少しずつですがわかってきました 有難うございます
で、記述ミスっててんやわんやしてる自分がいる・・・
|
34 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/27 14:46
うわー! Kタンありがとう!!! 助かります!!!。 (つか、まーたKタンに助け船を出されてしまいました。嗚呼、情けなや・・・ (T∀T) もっと昇進しなくては・・・) ↑ これは、「要石」ですので。Kタン感謝してます
ってなわけで、こんなのを書いてみる。 これでいけるぞぉぉぉ!
------------------------------------------------ [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100
;画面クリア ;カーソルを0,0に設置して ; MOV BH,0 ; MOV DH,0 ; MOV DL,0 ; MOV AH,0x02 ; INT 0x10
;全画面消去(80文字24行) ; MOV AL,0 ; MOV BH,0 ; MOV CH,0 ; MOV CL,0 ; MOV DH,24 ; MOV DL,80 ; MOV AH,0x06 ; INT 0x10
MOV CX,5 ;ループのカウンタ JMP PTCHA
PTCHA: ;文字を表示するループ MOV AL,0x41 MOV AH,0x0e INT 0x10
LOOP PTCHA
JMP ENDPG
ENDPG: ;ループからの脱出を確認するためにBを表示 MOV AL,0x42 MOV AH,0x0e INT 0x10
;BIOSのキー入力を乗っ取る MOV WORD[0x09*4+0],IINT09 MOV WORD[0x09*4+2],0
JMP GULGUL
;キー入力を待つループ GULGUL: JMP GULGUL
IINT09: MOV CX,5 MOV AL,0x43 MOV AH,0x0e INT 0x10
JMP ENDPG
EEND: ;MS-DOS終了 INT 0x20
--------------------------------------------------------
・・・・あっれぇ??? ウンともすんとも言わないなぁ。 間違っていないはずなんだが・・・・・
は!!!
割り込み許可・・・・ これか!!!!!!
|
35 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/27 15:07
うーん。なるほど。割り込みにはジャンルがあると。
●なにやってもどーしても、CPUの仕様として発生する割り込み ●CPUの仕様として決まっている。しかし許可したり禁止したりできる ●もともとはない。プログラマが好きに設定できる(しなくてもいい)割り込み
・・・・私の現在の想像。
たぶん、MS-DOSが走っている上体では、禁止できる割り込みは禁止されている。(今回のキーボードとか) だってそうしないと、勝手にチンチンバラバラと割り込みを処理されてしまうから。 キーボードの割り込み(入力の発生と検知)はみんなMS-DOSが受け持つような仕様になっている。 いま、私はアセンブラで、割り込みが発生した場合にジャンプすべき場所を書いてあるところ(割り込みベクタテーブル)を書き換えて、私が書いたプログラムへジャンプするようにした。 しかし、そもそもキーボードの割り込みは発生しない。(もしくは、発生しても弾かれてしまっている) キーボード割り込みが不許可(マスクされている)から
先に、とにもかくにも「キーボードの割り込み」だけでも許可をしておかないと、このプログラムは動かない
・・・・かな? えーっと・・・割り込みの許可は・・・・フラグレジスタ? どれじゃどれじゃ・・・・(がさごそ)
|
36 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/27 15:25
うーん。おっかしなぁ。どこ探してもそんなレジスタが見つからないなぁ。。。
・・・・ベースアドレス0x21と0xF7・・・・・
これか!?? これなのか???
|
37 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/27 15:39
んんん??? レジスタ!? 0x20と0xF7を、レジスタ「みたいに」使っているってこと???
え? じゃあ、0x20と0xF7に、00000000(0x0)を代入すれば、全ての割り込みが許可されるってこと???
|
38 Re: INT 0x09 の乗っ取り
名前: -- K 2004/9/27 16:25
ああそうか、DOSで動かしている場合もあるんだっけか。 それなら、
MOV WORD [0x09*4+0],INT09 MOV WORD [0x09*4+2],CS
にしてください。0ではなくてCSです。OSとして(?)起動した場合はいつもCSが0だったので、忘れていました。
なお、キーボード割り込みは既に許可されているはずです。 そうでないと、MS-DOSもキー入力ができません。
|
39 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/27 22:22
たーー! くっそ!アカンぜよ・・・(T∀T)
おっかしいなぁ。これでAをずーっと書き続けて、キーボードを押すと、それがBになるはずなんだけどなぁ・・・
------------------------------------------------ [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100
;表示文字「A」をセット MOV AL,0x41
;BIOSのキー入力を乗っ取る MOV WORD[0x09*4+0],IINT09 MOV WORD[0x09*4+2],CS
;ループにジャンプ JMP GULGUL
;キー入力を待つループ GULGUL:
;ループが廻っているのがわかるようにALレジスタの文字を表示 MOV AH,0x0e INT 0x10
JMP GULGUL
IINT09: ;ALレジスタの文字を「B」に切り替える MOV AL,0x42
RET
EEND: ;一応保険 ;MS-DOS終了 INT 0x20 ------------------------------------------------------
・・・ところで、今回Kタンにもらったアドヴァイスなんだけど、ん??? 物理的な絶対アドレスって、書き込めるのか? WORDってなんじゃらほい???
もーすこし研究してみないと。
|
40 Re: INT 0x09 の乗っ取り
名前: -- K 2004/9/27 23:48
ああそうか、DSだって0とは限らないわけか! 僕ってかなりそそっかしいな。
MOV WORD [0x09*4+0],IINT09 MOV WORD [0x09*4+2],CS
これは失敗で(すみません!)、
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をもとにもどす。
が正解でした。
ちなみに、RETはCALLに対するもので、INTに対するものはIRETです。
|
41 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/28 1: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. 2004/9/28 1:11
>WORDってなんじゃらほい??? アセンブリにはC言語のような型宣言が無いので, メモリに アクセスするたびに型 (大きさ) を明示するのです。WORDは 2バイトです。
中身に関するツッコミです。 割り込みルーチンに進入するときはレジスタの中身は不定ですし, どこへ帰るのかも不定なので, 期待どおりには動かないかと 思います。BIOS内部で割り込みに分岐しないという保証はあり ません。いやむしろ割り込み要因をクリアしてないからint9が かかった時点でおかしくなるんじゃないかな? 詳しくは分かり ませんが。
しっかし……イキナリ割り込みプログラミングとはチャレンジャー ですなあ。hideyOSiを作っているというのを初めて見たときは テキストVRAMをいじるあたりからやるのかと思っていました (←意味無くBIOSを避ける思考)。
|
43 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/28 1: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 2004/9/28 1:45
よかったー。
I.Tak.さんの懸念はもっともなのですが、この場合はこれでうまくいくはずだと思っておりました。 無事にうまくいって、僕も嬉しいです。あまり突っかかると、naskを疑われる心配が(笑)。 何はともあれ、割り込みの雰囲気がつかめたのはとてもよいと思います。
|
45 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/9/30 6: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 2004/10/2 2:48
おお、頑張ってますねぇ流石です
CSがコードセグメント DS,ESがデータセグメント(FS,GSは8086には含まれなかったような) SSがスタックセグメント でしたね
CSは今実行しているコードのアドレス DS,ESは実行しているコードがメモリにアクセスするときに参照するアドレス SSはPUSH等の命令のときに格納、参照するやつ という感じだったと思います
MOV命令は 汎用レジスタには汎用レジスタとオフセットアドレスと即値 セグメントレジスタには汎用レジスタやラベルとかで即値は入らないとのことです
って、何だこの時間は!
|
47 Re: INT 0x09 の乗っ取り
名前:hideyosi 2004/10/2 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 2004/10/2 13:48
>>feel氏
あ、そうそう。個人連絡的で恐縮ですが。
feelさんって、以前、ブートローダーを試作なさいましたよね? もう引っ込めてしまわれたようですが、もし(ほんとにもし)よろしければ、 私に見せて頂くことはできませんか?勉強させていただきたいのですが。 トップページに書いてありますが、当サイトのディフォルトライセンスはKL-01です。これに準拠したくない場合は、明記いだだければ。 (もちろん、「お前さんには見せてあげるが、公開しちゃダメ!」ってのも、ありです。いずれにしても、原作者であるfeelさんの意向に全面的に従いますので)
是非、ご検討いただけましたら幸いです。
|
49 Re: feelさんへ
名前:YARMA 2004/10/2 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 2004/10/2 18:51
公開するのは全然構いません 見難い点がかなりありますが ここにソース載せたほうがいいですかね? それともリンクがいいですか? もしくは、sutekata@yahoo.co.jpにでも連絡を >>YARMA 消す、消さないはあなたの判断に任せます それよりも新しいのが出来ているのでね
|
51 Re: feelさんへ
名前:hideyosi 2004/10/2 19:08
>公開するのは全然構いません
わー。ありがとうございます!うれしいです。
>ここにソース載せたほうがいいですかね?それともリンクがいいですか?
feelさんが一番楽な方法で。(なにしろこっちはお願いする立場ですから (^^) )
たとえば、私にメールなどで送っていただいたりして頂ければ、 私のほうでHTMLに変換するなりさせて頂きますが。 ん? あ、そか。YARMAさんとこにあるのか。 YARMAさんとこから頂いて、とりあえず当方で公開なり研究なり。 っということでよろしいですか?
あ、あと、ライセンスなんですが。KL-01でいいですか?ほかになにかご希望とか?
|
52 Re: feelさんへ
名前:hideyosi 2004/10/2 19:15
>>49 YARMAさんごめんなさい。表示が乱れてしまうので、 勝手ながら、元のメッセージを編集しました。 なにとぞご理解を。 ペコ m(_ _)m
|