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
|
53 Re: feelさんへ
名前:feel 2004/10/2 19:33
私はライセンスとかはどうでもいいのでそちらにお任せします 一番最近のやつを渡したいので後でメールで送らせていただきます ただ、今製作用のPCにOS入れてないのでちょっと待って下さい それまでは古いほうでも見てて下さい どちらもあまり誇れませんが・・・
|
54 Re: feelさんへ
名前:hideyosi 2004/10/2 19:54
feelさん、気持ちよくご了承をしてくださり、ほんとうにありがとうございます。
>一番最近のやつを渡したいので後でメールで送らせていただきます
いやもう、ほんとにお暇な時にでも。楽しみに待たせて頂きます。
>私はライセンスとかはどうでもいいのでそちらにお任せします
了解いたしました。あ、でも、KL-01は、あとでいつでもライセンスの変更が容認されているライセンスですので、なにかありましたらいつでもご一報くださいね。
>どちらもあまり誇れませんが・・・
とんでもありません! 謹んで勉強させて頂きます。
|
55 Re: feelさんへ
名前:feel 2004/10/2 21:01
良し、OK Mandrakeインストール完了 で、さっきのメアドで送らせていただきます で、もしものときの保険 http://jp.y42.briefcase.yahoo.co.jp /bc/sutekata/lst?.dir=/&.view= こちらにもおいておきます
|
56 Re: feelさんへ
名前:feel 2004/10/3 18:15
コメント追加 リンクのみとさせていただきます http://jp.y42.briefcase.yahoo.co.jp /bc/sutekata/lst?.dir=/&.view= 前書いたやつと同じです ああ、適当なこと書いてるかも・・・
|
57 Re: K氏のheboOSをまねてみる
名前:I.Tak. 2004/10/7 12:19
独り言Wikiの NASK/文法 につっこみ! 誰もつっこまないのか……?
>MOV AX, AL サイズの違う代入はできません。符号あり/なしの問題があるので, MOVZX AX, AL ; 符号無し拡張 MOVSX DX, CL ; 符号付き拡張 を使います。
>MOV [0x100],[0x200] MOVではメモリ間コピーはできません。
>MOV [0x100], 0x1F メモリの大きさを指定してください。byteで書くべきところにwordで書いたら大変ですよ!
>ADD AL, AX >SUB AL, AX サイズの違う演算は(略
>JMP [0x400] ;「セグメント値+400」番地にジャンプし、実行を始める こいつは "オフセット0x400からオフセット値(リアルモードではwordサイズ)を読み込んでそこへジャンプ" します。 ブラケット[]で囲ってあるのは LEA 以外全てメモリアクセスをするのです。 オフセット0x400 へのジャンプは単に JMP 0x400 とします。
>LOOP ; CXレジスタがゼロになっていない限り、指定したアドレスにジャンプする。 CXから1を引いて, 0にならない限り, 指定のオフセットへジャンプします。……が, ジャンプできる距離が -128〜127 と狭いので注意。
>LOOP [0x200] LOOPはメモリからジャンプ先を読み込むことができません。必ずラベルを指定します。
>CALL サブルーチン処理にジャンプする前に, 戻る場所のオフセット値をスタックに積みます。 RETで戻れるのはそういうカラクリなのです。
アドレスは必ずセグメントとオフセットの組で指定するものですが, セグメントから出る気がなければ, アドレス=オフセットで話は通じます 気合と余裕がありあまっていれば, Intelのマニュアルの中巻 (インストラクションマニュアル) を眺めてみると面白いかもしれませんよ。
|
58 Re: K氏のheboOSをまねてみる
名前: -- K 2004/10/7 12:48
>誰もつっこまないのか……?
あれはhideyosiさんによるhideyosiさんのためのメモだと思っているので、うわーわからん、もうどうしたらいいだー、「誰か教えて」というまでは、あれこれ言わないほうがいいと僕は思って、言いませんでした。
理解には段階があって、今のうちから符号付き拡張・符号なし拡張をどうこういっても、かえってhideyosiさんは混乱しちゃうんじゃないかなあ。現段階としては何も分からなかった状態から、代入はMOV、加算はADD、減算はSUB、とかが把握できていることが快挙なので。英語で言えば基本動詞が理解できて、前置詞の細かい規則や、この言い回しはCPUの都合でできるとかできないとかは、ちょっとつらいのではないかと。
|
59 Re: K氏のheboOSをまねてみる
名前:I.Tak. 2004/10/7 16:05
hideyosiさんが混乱しかねないというのは分かります。 しかし, ちょっとNASKを動かせば分かる間違いを公開したまま, というのはやはりどうかと思うのですよ。これがNASKの文法だ! というページですし……
|
60 Re: K氏のheboOSをまねてみる
名前:hideyosi 2004/10/7 18:19
>しかし, ちょっとNASKを動かせば分かる間違いを公開したまま
いや、まったくI.Tak.さんのおっしゃる通りです。いろいろとやってメモしている真っ最中になんやかやと大忙しになってしまい、実験や検証をしないままけっこうそのまんまになってます。えらい粗相で、おはずかしいです。
いま、ちょっと忙しくて手がつけられません。とりあえず「勉強中、合ってないとこあり!」的なコメントを付加しておきます。
>NASKの文法だ! というページですし……
おっしゃるとおりです。私のポカだけならまだしも、これを見たどなたかが勘違いでもしてしまっては大変です。
>誰もつっこまないのか……?
>あれこれ言わないほうがいいと僕は思って、言いませんでした。
お二人のお気遣い、とてもありがたいと思っています。
しかし、いずれにしても、今ちょっとまったく動けない状態でして。(今夜が峠なんですよねぇ。明日になれば・・・)
恐縮ですが、今しばらくのご猶予を。
|
61 Re: K氏のheboOSをまねてみる
名前:YARMA 2004/10/7 18:51
>しかし、いずれにしても、今ちょっとまったく動けない状態でして。(今夜が峠なんですよねぇ。明日になれば・・・)
もとはといえば結局僕が起こしたことがきっかけでこんなことになっちゃったんだよなぁ・・・ このプロジェクトを復活させようとしているhideyosiさんに本当に申し訳ない。こんな馬鹿な僕ですが、できる限り(これからは通りすがりとして)足手まといにならない程度に活動しようと思っています。本当にありがとう。
|
62 nask
名前: -- K 2004/10/7 20:28
>hideyosiさんが混乱しかねないというのは分かります。 >しかし, ちょっとNASKを動かせば分かる間違いを公開したまま, >というのはやはりどうかと思うのですよ。これがNASKの文法だ! >というページですし……
確かにその意味はわかります。つまり他の人が見るかもしれないわけで、正しくない情報はいかんということですよね。
僕としては、hideyosiさんが「間違っている可能性あり」って明記してくれるそうなので、それで十分だと思っています(まあ無くてもいいかなとは思っていますが)。
このWikiはhideyosiさんしか書けなくなっていて、つまり正しいよりよい情報を集めるということよりも、単にhideyosiさんのワークスペースを公開しちゃっただけ、に思うのです(確か最初にWikiを作ったときにも、自分の頭の整理のために作ったと書いていたような気がしますし)。
間違いが気になるのは分かりますが、それならせめて、「○○という記述はやってみたけどうまく動かなかったよ」くらいの、障害報告程度でとめておくことはできないでしょうか。次々と正解を示すことは、かえってhideyosiさんがつらくなってしまうと思うんです。さらに、このスレッドをゆっくり追いかけてアセンブラを勉強する人が今後出てくるかもしれませんし、そんな人のためにも、hideyosiさんが自分のペースで学習できるように、協力していただけないでしょうか。
もちろん、当のhideyosiさんがお手上げでhelpを求めたときは、その部分についての正解を示すことはとてもよいと思います(まあそのときも、できるだけ新しい知識に触れないようにしたいですが)。
|
63 Re: nask
名前: -- K 2004/10/7 20:39
追伸:
ちなみに僕は、書き間違いについても、できればhideyosiさんが自分で気がついてほしいと思っています。これでいけると思っていたけど、実はやってみたらうまくいかなかった、そんな過程でまたかしこくなっていくわけで。そういう過程をスキップさせてしまうことは、効率がいいかもしれませんが、なかなか身につかない結果になったりします。
hideyosiさんが自分でなんとかがんばろうとしている間は、できる限りノーヒントでいましょうよ。頼まれもしないのにあれこれいうのは、控えめで。
もしちゃんとしたnaskのサイトを作りたければ、それはI.Tak.さんや僕などが別途作ればいいと思うんです。hideyosiさんは、自分の学習のためにあのWikiを作ったのであって、他の人が満足するようなマニュアルを作ろうとはしていないと思うんです(もちろん、最後にはあのサイトは立派なマニュアルになるのかもしれませんが)。その辺の意図を汲んであげてほしいんです。
|
64 Re: nask
名前:I.Tak. 2004/10/8 14:21
考えてみると, 確かにお節介が過ぎたようです。IntelなりNASMなりのマニュアルに誘導するだけで十分だったと反省しています。 検索などで一部のページのみを見られることもありますから, hideyosiさんがSOSを出すまで完全に放置しようとは思いませんが (←NASKユーザとしての一種のファン意識), 生暖かく見守ることにします。
|
65 Re: nask
名前:hideyosi 2004/10/9 15:35
>考えてみると, 確かにお節介が過ぎたようです。
えーー! そんなぁ! そんなこといわずに、お節介焼いてください!
>NASKユーザとしての一種のファン意識
いやいやいや!これはよーく解りますよ。たしかにあのまんまじゃ、「おい知ってるか?ガンダムってさ、ロボットで、合体するんだぜ?」って言われてるよーなもんですもんね。
おかげさまで、例の件はほとんど片付きました。いよいよアセンブラのお勉強再開です。どうぞ、生暖かくと言わず、サイリックスのCPUの如く見守ってくださいませ。 m( )m
|
66 Re: nask
名前:hideyosi 2004/10/9 15:39
さーて。それではオゲンキョ再開。
KタンやI.Tak.さんのおかげで、キーボードの乗っ取りはできるようになった。
こんどは、その乗っ取った後の処理をかんがえなくちゃ。 一番最初にしなくちゃいけないのが、「なんのキーが押されたか?」という処理。
えーと・・・・どこいらへんから手をつけようかな???
|
67 Re: nask
名前:MiSt 2004/10/9 19:27
THE-BBLからは退会しましたが、 このPJの様子を時々見守らせてもらっております。 で、 http://konoxos.client.jp/src/1.0/a4/000004/shell.asm に、昔の16bitKONOXのシェルソースがあります。(NASMですが)
参考程度にどうぞ。
|
68 Re: nask
名前:MiSt 2004/10/9 19:27
ちなみに上のshell.asmはリアルで動作します。
では、失礼します。
|
69 Re: nask
名前:feel 2004/10/9 22:39
確か MOV AH,00H INT 16H で、ALにコードが出力されたような気がします ここで使うのかどうかは分かりませんが・・・
http://lrs.fmi.uni-passau.de/support/doc/ interrupt-57/INT.HTM こことか見ると良いかもしれません
|
70 Re: nask
名前:YARMA 2004/10/10 10:12
↑このページどっかで見たことがあるな・・・
あ、そだ、THE-BBLのWikiにあったあった。 たしか、昔破壊したページで今は「過去の遺跡」に納められてたっけw あ、でも、もう「お袋」は抹消して、バックアップにしか残ってないやぁ
(「お袋」とは?・・・昔Wikiにあった掲示板。今は通りすがり3の意見により、破壊済み。Ofukuro has already been clashed.(←英文あってるか気にしないでください。
で、「お袋」に.oOo.氏が
ここには初めて書き込みます。 参考に→ http://www.ctyme.com/ intr/int.htm -- .oOo.? 2004-08-24 (火) 00:56:48
と、・・・あれ、アドレスが違うぞ?まぁ、ぃぃゃ気にしない
|
71 Re: nask
名前:hideyosi 2004/10/11 20:37
えーっと。なになに? アセンブラでは、周辺機器との入出力には、「IN・OUT」命令を使うと・・・。
周辺機器はいっぱいある。(キーボードだったりディスプレイだったり・・・)この場合、「どの周辺機器のデータを持ってくる?」という指定が必要になるな。
なにしろアセンブラだから、きっと8ビットとか16ビットの番号が振ってあって、ある程度決め打ちになっていると思われる。 こういうのの一覧表ってあるのかな?
|
72 Re: nask
名前:hideyosi 2004/10/11 20:41
うーん・・・・これなのかなぁ?
http://community.osdev.info/index.php?cmd=read&page=%28AT%29iomap
・・・ん? ある入門書に、入出力の実験には、システムスピーカーが最適とある。えーっと。システムスピーカーの番号は・・・・
え” 0061番!? あっれー? OS Wikiのデータだと、「システムステータス」となっているぞ???
|
73 BEEP
名前: -- K 2004/10/11 20:47
これをみれば、もしかしたら分かるかな?
http://community.osdev.info/index.php?(PIT)8254
というか、つまり、システムポートというところがあって、 それはI/Oポートの0x0061番で、そこにはいろんな機能があって、 その一つがBEEP制御なのです。
|
74 Re: BEEP
名前:hideyosi 2004/10/11 22:31
>というか、つまり、システムポートというところがあって、 >それはI/Oポートの0x0061番で、そこにはいろんな機能があって、 >その一つがBEEP制御なのです。
・・・あぁぁぁぁぁ!!! なるほどぉ!!! つまり、0061番のI/Oポートは、それ1つで「BEEP」だとか、「xxx」とかの機能をもっているんじゃなくて、そのビットひとつ1つに意味があるのか!!!
・・・うへぇ! じゃ、0061番地に単純に0x○○を代入するのはまずいのか!!!! だって、他のビットがなにか意味をもっている場合、そいつを勝手に書き換えちゃうと、なんか勝手に動作とかしちゃうじゃないか!
うむむむ・・・・ ってことは、0061番地の、一ビット目と2ビット目だけを、1にしなきゃいけないわけだ。
・・・うはぁ! もしかして、「ビットシフト」とかなんとかをやらなくちゃいけないの???
ひえー・・・。まーた別の勉強しなくちゃ・・・(T∀T)
|
75 Re: BEEP
名前:hideyosi 2004/10/11 23:04
わー! わかった!!!! ORだ!!!
|
76 Re: BEEP
名前: -- K 2004/10/11 23:19
もしうまくいかなかったら、
http://community.osdev.info/index.php?(PIT)8254
の下のほうにある「ものぐさなひとのために」を参考にしてください。
|
77 Re: BEEP
名前:hideyosi 2004/10/11 23:45
そんなわけで、こういうコードを書いた。 これで、ビープは鳴り出した。一応成功である。 なんか突っ込みあったら・・・(もっといい方法とか)
--------------------------------------------- [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;-----------------------------------------------------
;-------- 実験部分 ---------------------- ;IN・OUTは、DXレジスタに、対象となるI/Oアドレスを ;入れてから行う。今回は0x0061 MOV DX,0x61
;まず、現在の0x0061の内容を一旦持ってくる IN AL,DX
;持ってきた内容の内、一番目と2番目のビットだけ、1に ;する。そのためには、 00000011 すなわち、0x03で、 ;持ってきた内容にORをかける。こうすると、一番目と ;二番目だけが1になり、あとはそのまんま変化しない。 OR AL,0x03
;出来上がった内容を、再び0x0061番地に書き戻す。 OUT DX,AL
;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20
----------------------------------------------------------
|
78 Re: BEEP
名前:hideyosi 2004/10/11 23:58
キーボードの押されたキーの取得。
なになに? 押しっぱなしなのか、話したのかとかの判断もあるのか・・・うわー。こりゃ大変かもしれないぞ!?
まあいいや。とにもかくにも、まずは取得してみる実験だ。
えーっと。「A」のキーが押されると、1Eが帰ってくるはず。 そうすると、たとえば、例の割り込み先に、
1、I/Oポート 0x0060 を読め! 2、読み込んできたデータを、0〜6に絞れ。 3、絞ったデータがもし 1E だったら、「A」が押されている。画面にAを書け!
・・・みたいな、こんな感じのコードを書けばいいのか!
|
79 Re: BEEP
名前: -- K 2004/10/12 0:14
>押しっぱなしなのか、話したのかとかの判断もあるのか・・・
キーボードは結局ただのスイッチです。 スイッチが、 off→on になることをメイク(make)といいます。 逆に、 on→off になることをブレイク(break)といいます。
ということで、もし0x7fでANDしてしまうと、押したときも離したときもAが出ると思います(つまり1度おすと2つ出る)。
|
80 Re: BEEP
名前:hideyosi 2004/10/14 22:27
さて。そんなわけで、私はとりあえずこんなコードを書いてみた。
------------------------------------ [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;-----------------------------------------------------
;-------- 実験部分 ----------------------
;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 MAINLLP ;メインループへジャンプ
;メインのループ部分 MAINLLP:
JMP MAINLLP
;乗っ取ったキーボード割り込み部分 IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX
;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする
;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする
JE MOJIPRINT
;そうでなかったら、割り込みから戻る IRET
;文字を表示するルーチン MOJIPRINT: MOV AL,0x41 MOV AH,0x0e INT 0x10
IRET
;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20
-----------------------------------------
ちなみにこれは、「一部成功一部アカン」でした。 これを実行し、「一回目」のキーボタンがAなら、ちゃんとAを表示していますが、それ以降は無反応になってしまいます。
・・・っということは、「押されたのがAじゃなかった場合」の処理に問題があるのでしょう。えとえと。こういうのって、どうやってデバッグするのかな? もしかして、DEBUGコマンドを使うのかな???
|
81 割り込み処理
名前: -- K 2004/10/14 23:52
おめでとうございます!
>これを実行し、「一回目」のキーボタンがAなら、ちゃんとAを表示していますが、それ以降は無反応になってしまいます。
いや、それでよいのです。なぜ無反応になってしまったかというと、割り込み処理が完了したことを、CPUにしか知らせてないからです。
くわしいことは、
http://community.osdev.info/index.php?(PIC)8259A
をじっくりと見てください(特に最後の「ものぐさなあなたのために」を見逃さないように)。
|
82 Re: 割り込み処理
名前:hideyosi 2004/10/16 15:45
ふむ!?
Kタンのhttp://community.osdev.info/index.php?(PIC)8259Aをジックリと読んでみた。 ・・・むずかしくてわかりません・・・(T∀T)
しかし、そんなぼくらのために(ヲレだけかも)「ものぐさ」というセクションがあった。
ようするにはこういうことらしい。 ●割り込みは、CPUの機能だが、その割り込みの発生・CPUへの発注・関所を行うLSIがあるらしい。 ●このLSIは、キーボードなどから信号が来ると、割り込み信号を作って、CPUに「おい!割り込みがきたぞー!」と知らせ、CPUでは割り込みが発生する。 ●CPU(アセンブラのプログラム部)では、割り込み時に必要な処理は行う。で、その処理が終わったら、IRETで戻ってくる。(つまり、CPUとしては、割り込みは終了している) ●問題は、さっきのLSI。この時点では、まだ、「割り込みがキタゾー!」のまんま。つまり、次の割り込みは待たされている ●つまり、このLSIにも、「CPUとしては、割り込み処理はもう終わったよ。次の割り込みを受け付けていいよ。たのむね」と、教えてあげなくてはいけないらしい。
そのためのコードが、これらしい。
AL = 割り込み番号 + 0x60; OUT(0x20, AL);
|
83 Re: 割り込み処理
名前:hideyosi 2004/10/16 16:15
うーーーん・・・ AL = 割り込み番号 + 0x60; OUT(0x20, AL); これはどういうことだろう。こういうことなのかな???
-----------------------------------------
[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;-----------------------------------------------------
;-------- 実験部分 ----------------------
;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 MAINLLP ;メインループへジャンプ
;メインのループ部分 MAINLLP:
JMP MAINLLP
;乗っ取ったキーボード割り込み部分 IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX
;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする
;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする
JE MOJIPRINT
;そうでなかったら、割り込みから戻る JMP INTEND
;文字を表示するルーチン MOJIPRINT: MOV AL,0x41 MOV AH,0x0e INT 0x10
JMP INTEND
;割り込み後は、この処理をしないと戻れない INTEND: MOV AL,0x09 ADD AL,0x60 MOV DX,0x20 OUT DX,AL IRET
;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20
-----------------------------------------
・・・ところが、これだとうまくいかないんだよねぇ。なんでだろう????
|
84 Re: 割り込み処理
名前:hideyosi 2004/10/16 16:22
っはっはぁぁぁぁ。 なるほどぉ! この場合の「割り込み番号」って、IRQ番号を使うんだぁ! えーっと、キーボードのIRQって・・・・1か!
つまり、こうするわけか?
-----------------------------------------
[BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;-----------------------------------------------------
;-------- 実験部分 ----------------------
;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 MAINLLP ;メインループへジャンプ
;メインのループ部分 MAINLLP:
JMP MAINLLP
;乗っ取ったキーボード割り込み部分 IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX
;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする
;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする
JE MOJIPRINT
;そうでなかったら、割り込みから戻る JMP INTEND
;文字を表示するルーチン MOJIPRINT: MOV AL,0x41 MOV AH,0x0e INT 0x10
JMP INTEND
;割り込み後は、この処理をしないと戻れない INTEND: MOV AL,0x01 ;キーボードの割り込み(IRQ) ADD AL,0x60 ;その番号に、60を足した値 MOV DX,0x20 OUT DX,AL
IRET
;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20
-----------------------------------------
おぉぉ!!! うまくいったぞ!!!! 逆にKタンの懸念どおり、一回押せば2回Aが出てしまうってのもちゃんと?再現。
よぉぉぉぉし!!!!!!!うまくいったぞ!!!
|
85 Re: 割り込み処理
名前:hideyosi 2004/10/16 19:16
さてさて。この実験用のショボイコードも、けっこういろいろと できるようになってきた。 これを、とにもかくにもOSっぱく見えるところまで仕上げてみよう。 そのためには、
1、プロンプトを表示してみよう 2、例の、一回押すと二個文字がでる現象をなんとかする 3、キーボードからの文字をちゃんと認識できるようにする 4、一個ぐらい、コマンドを実装したいなぁ(clsとか)
そんなわけで、まずは2から手をつけよう。
|
86 Re: 割り込み処理
名前:hideyosi 2004/10/16 22:04
まず、キーボードからやってくる、「押されたキー信号」は、 0〜6までがキーを示す値。で、最後の7bit目が、「押したのか・離したのか」をあらわします。 今現在、私のコードでは、押して一回、離して一回と割り込みを処理してしまっていますので、一回キーを押すと二回「A」が表示されます。 「キーが離されたときだけ」という反応をすれば、OKなのではと考えました。
今現在はこういうコード。
--------------------------------------------------- IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX
;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする
;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする
JE MOJIPRINT
;そうでなかったら、割り込みから戻る JMP INTEND -----------------------------------------------------
これを、こうしてみたらどうだろ?
------------------------------------------------------ IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX
;持ってきた値を一時、AHに複製する MOV AH,AL ;AHに複製した値の7ビット目だけを摘出 AND AH,0x80 ;もし、この結果の値が00000000すなわち0x0なら、 ;キーは「押された」となるはず。ここで条件分岐 CMP AH,0x0
;なにもせずに割り込みを終了する JE INTEND
;違うなら、キーは「離されて」いる。 ;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする
;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする
JE MOJIPRINT
;そうでなかったら、割り込みから戻る JMP INTEND ---------------------------------------------------------
さて。これでうまくいくかな???
|
87 Re: 割り込み処理
名前:hideyosi 2004/10/16 22:09
うはははは! いよーし!! うまくいったぞ!! (^^)
次は、A以外のキーも反応できるようにしょう!
|
88 Re: 割り込み処理
名前:hideyosi 2004/10/16 23:50
うーーーん・・・・ 押されたキーと、ASCIIのキーコード。なんらかの法則性があるかと思って眺めていたんだけど、まったく関連性がないや・・・ なんらかの計算ルーチンでなんとかなるかと思っていたが、甘かった・・・・ やっぱ、基本的には「絨毯爆撃」で分岐を書くしかないのかなぁ・・・
|
89 Re: 割り込み処理
名前:hideyosi 2004/10/18 1:01
いろいろと考えてみたんだけど、やっぱほかにいい方法がみつからないや。もういいや!絨毯爆撃で!
・・・ってなわけで、キーボードの割り込み部分はこういうふうになった。
------------------------------------------- ;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E
;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする JE APRINT
CMP AL,0x30 ;Bが押されている JE BPRINT
CMP AL,0x2E ;Cが押されている JE CPRINT ・ ・ ・
CMP AL,0x15 ;Yが押されている JE YPRINT
CMP AL,0x2C ;Zが押されている JE ZPRINT
;そうでなかったら、割り込みから戻る JMP INTEND
;文字ごとにコードをセットする APRINT: MOV AL,0x41 JMP MOJIPRINT
BPRINT: MOV AL,0x42 JMP MOJIPRINT ・ ・ ・ YPRINT: MOV AL,0x59 JMP MOJIPRINT
ZPRINT: MOV AL,0x5A JMP MOJIPRINT
;文字を表示するルーチン MOJIPRINT: MOV AH,0x0e INT 0x10
JMP INTEND ----------------------------------------------
で、コンパイル。 おぉぉ!!! 文字がいろいろと表示できる!けっこうたのしいぞ!!
今回はとりあえず、ABC・・・XYZまでだけにしておこう。他のキーやShiftとかはちょっと後回し。
・・・でも、ENTERキーだけは、なんとかそれらしく動作させたいなぁ。
|
90 キーコード変換
名前: -- K 2004/10/18 14:04
>おぉぉ!!! 文字がいろいろと表示できる!けっこうたのしいぞ!!
おめでとうございます。
>いろいろと考えてみたんだけど、やっぱほかにいい方法がみつからないや。もういいや!絨毯爆撃で!
ちょっとだけヒントを書くことにしようかな。
アセンブラでもCでも同じことですが、この手のコードをifのかたまりやswitchのかたまりで書くのは良くないことです。C言語であれば、
static char table[] = { 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*' (以下略) };
とやっておいて、 j = table[i]; とでもすれば、一発でキーコードから文字コードにできます。
おなじことをnaskですることもちろんできて、
; ALには0x1eなどのコードが既に入っているとする。
MOV BH,0 MOV BL,AL MOV AL,[BX+table]
; これでもうALには文字コードが入っている。たくさんのCMP+JEにさようなら。
; 以下はプログラムではなくデータなので間違って実行しないような位置におく
table: DB 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 8, 9 DB 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 10, 0, 'A', 'S' DB 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V' DB 'B', 'N', 'M', ',', '.', '/', 0, '*' (以下略)
僕の書いた意味が理解できたら使ってみてください。 理解できなければ今のままCMP+JEで書くほうがいいと思います。 MOVしか使ってないので、努力すれば理解できるのではないかと思って書いてみました。
ちなみに、'A'などの表現が見慣れないかもしれませんが、これは0x41のことです。 MOV AL,'A' とかもできます。
|
91 Re: キーコード変換
名前:hideyosi 2004/10/18 23:21
ENTERキーの処理。 まず、ENTERキーの分岐をおきます。これは簡単。
------------------------------ ;ENTER キー CMP AL,0x1C ;Zが押されている JE ENTERPRINT --------------------------------
で、このENTERPRINTってラベル以下にコードを書けば出来上がり・・・
------------------------------------------------ ENTERPRINT: ;BIOSでカーソル位置を設定 MOV AH,0x02 MOV BH,0x0 MOV DL,0 MOV DH,Y座標 INT 0x10
JMP INTEND -----------------------------------------------
・・・・あれれ? この場合、Y座標の値ってどうするんだ?
順当に考えると、「現在のY座標+1」ってことだよね? むむむ?? 「現在の座標」って、どうやって求めるんだろう? さっそくいろいろと調べてみた。 なになに? 0040:0050hがそうだって??? うむむむ??? どうもよくわからないや。こりゃ、実験しかないか!?
|
92 Re: キーコード変換
名前:hideyosi 2004/10/18 23:34
うーん・・・0040:0050hという表現。これまでのパターンだと、これは、セグメント:オフセットのパターンではないかなぁ?
そうすると、この0040:0050hという場所の値を読み出すには
------------------------------------------- MOV AX,0x40 MOV ES,AX ; ESを0040にする。 MOV AX,WORD[ES:0x50] ーーーーーーーーーーーー---------------
こういうコードになるのかな???
|
93 Re: キーコード変換
名前:hideyosi 2004/10/19 1:06
だあぁぁぁぁぁぁ!!!!!
にゃんだよクソ!!! ちゃんとBIOSにあるぢゃん!
ってことで、こういうコードを追加して、目的の動作をしました。
------------------------------------------- ENTERPRINT: ;現在のカーソルの位置を取得(Y座標のみ) MOV BH,0x0 MOV AH,0x03 INT 0x10
;BIOSでカーソル位置を設定 MOV AH,0x02 MOV BH,0x0 MOV DL,0 INC DH ;上で取得した行位置+1 INT 0x10
JMP INTEND -------------------------------------------------------
|
94 Re: キーコード変換
名前:hideyosi 2004/10/19 3:32
上の状態だと、カーソルが最下行に行っちゃうと、固まったようになって画面が動かなくなっちゃう。 で、こんなコードに変更。
---------------------------------------- ENTERPRINT: ;現在のカーソルの位置を取得(Y座標のみ) MOV BH,0x0 MOV AH,0x03 INT 0x10
INC DH ;上で取得した行位置+1
CMP DH,0x19
;もし、最下行だったらロールアップ JE ENTERPRINTLUP
;そうじゃなかったら、普通にカーソル移動
JMP ENTERPRINTNML
ENTERPRINTLUP: ;ロールアップ。まず、ロールアップをする MOV AL,0x01 MOV BH,0x0F MOV CH,0x01 MOV CL,0x0 MOV DH,0x18 MOV DL,0x4F MOV AH,0x06 INT 0x10 ;カーソルを最下行にセット MOV DH,0x18 JMP ENTERPRINTNML
ENTERPRINTNML
;BIOSでカーソル位置を設定 MOV AH,0x02 MOV BH,0x0 MOV DL,0
INT 0x10
JMP INTEND --------------------------------------------------
おーー! まるでエディタの如く、最下行でロールアップするぞ!?
|
95 プロンプトの搭載
名前:hideyosi 2004/10/19 21:21
なんか、「見た目だけ」とはいえ、だんだんMS-DOSっぽくなってきて楽しいなぁ・・・。 そんなわけで、プロンプトを搭載してみよう。 これはそうむずかしくない。まず、テキスト画面を一旦クリアする。 で、プロンプトを表示する。 さらに、Enterキーが押されたら、とりあえず無条件でプロンプトを表示させると。
------------------------------------------------- ENTERPRINTNML
;BIOSでカーソル位置を設定 MOV AH,0x02 MOV BH,0x0 MOV DL,0
INT 0x10
CALL PROMPTPRINT
JMP INTEND
PROMPTPRINT: ;BIOSコールで文字列を表示 MOV AH,0x13 MOV AL,0x01 MOV BH,0x0 MOV BL,0x0F MOV CX,0x07 ;本来はここで、DLとDHで座標を指定するが、これは変わらないので ;いらないと思う MOV BP,pmsg INT 0x10 RET
;プロンプトの文字列 pmsg DB "THEBBL>"
-------------------------------------------------------
・・・・ぶははははは!!! できたできたー!
|
96 リリース!(ごっこ)
名前:hideyosi 2004/10/19 22:58
さーてと!! とりあえず、キリがいいので、この私のOS(は?)を、リリースして みよう。
hideyOS Ver 0.01ってことで。(笑
http://thebbl.hideyosi.com/age/hdOS001.lzh
・・・みなさんに笑って頂いてナンボですから・・・ (T∀T)
あ、あと、これまでのソースは、こちらから直で見られます。 アドヴァイスなんかしてみようなんて方は、是非・・・(^^;)
http://thebbl.hideyosi.com/age/test11.nas.txt
|
97 Re: リリース!(ごっこ)
名前: -- K 2004/10/19 23:13
早速楽しんでいます。.COMは374バイトで、Win2000のDOS窓でも動いています。
ささやかな要望を。キーを離したときに入力されるというのは、ちょっと脱力系なので、できれば押したときに入力されてほしいです。
あと、BackSpaceの処理が追加されたら、もっとそれっぽいかも!
さらに、最初に"hideyOS Ver 0.01"みたいなメッセージがあったらいいなあ。
それでは。
|
98 Re: リリース!(ごっこ)
名前:hideyosi 2004/10/19 23:22
>早速楽しんでいます。
ぐはぁ!!! よりによって、Kタンが試している!? 魚影〜!!! ゴロゴロゴロ・・・・ <恥ずかしくてのたうちまわっている
>できれば押したときに
・・・あ” そっかぁ。そいえば、押してときの動作って、やってみたことないなぁ。さっとくためしてみよう。
さて、ほいだば、Ver 0.02に向けてガンバロ! Ver0.02では、まず、キーボードの処理をなんとかする。Kタンにアドヴァイスしてもらった書き方の理解と勉強。当然、BSやShiftなんかの処理も搭載したいなぁ。
あと、とりあえず、なんらかのコマンドを搭載したい。たとえば、clsとか、rebootとか。
あと、現在は画面関係はみんなBIOSにたよっているけど、これをなんとかできないか実験してみよう。
|
99 Re: リリース!(ごっこ)
名前:feel 2004/10/19 23:49
試しました しっかり動きますね 私も頑張りたいと思います 頑張って下さい 家のウイルス対策ソフト(NOD32)が過剰反応してビビりましたが 何ともなくてよかったよかった
明日から修学旅行だぁ〜 京都へ台風と戦いに行ってきます そしたらまた頑張ります
|