/var/log/hdk.log

最新 5 日分


10 (火)

%1 8088

8086 Architecture

この図を見て悩まされている。ALU とつながる内部のバスが 16 ビット。 このバスは共用なのだろうか? つまり、複数の 16 ビットレジスターの内容を同時に ALU に食わせることはできないのだろうか? Temp.Registers の存在もあって、できないというのもあり得るとは思う。

問題はシフト命令のクロック数で、1 ビットのシフト命令は、なんと 2 クロックで済むということになっている。 シフト命令もフラグの反映があるので ALU での処理と見て間違いないだろう。 また、1 ビットシフトなので 1 入力 1 出力で、インクリメントなどの命令が 2 クロックというのに近い。 しかし、2 クロックの INC 命令が 1 バイトなのに対し、シフト命令は 2 バイトである。 そして 2 バイト目を見ないとどのレジスターに対する操作かがわからない。 レジスター同士の足し算などの命令は 3 クロックだが、全加算器がキャリーを処理していくのに時間がかかるからかとも考えた。 しかしそれでは論理演算命令も 3 クロックなのが説明できない。1 クロックの間に 2 バイト分の命令の処理ができるのか? 3 クロックかかる 2 バイト命令は 2 オペランドだからか? それも 2 バイト分の命令のデコードは 1 クロックで済んで、レジスターを 1 個ずつ内部バスで転送しているから 3 クロックなのか? ウーン... 2 バイト 2 クロックの MOV CS 命令の時に半分の時点で %cs が変わっているっぽかったのも気になるし...

2019/12/10 のコメントを読む・書く


11 (水)

%1 すいようび

12 月中旬にしてはやや暖かい日。 職場近くの銀杏の色づき具合が、先週頃は日当たりの差でバラバラになっていておもしろかったけど、だいぶマシになっていた。 とはいえ、まだほとんど散っていないあたり、去年以上に変な感じ。

夜帰る頃に、職場近くの駐車場に駐まっていた車が濡れているのに気づいて、あれ、雨降ったんだな、みたいな感じで、まったく雨に降られることなく帰宅できた。

%2 Portfolio

Grp3 の 1, TEST 命令の隣が TEST 命令かどうかを調べた。

 9c50f6c8019c50f6c8049c50 11311311 01B4 F102 01B4 F146 01B4 F102
 9cf6c0019cf6c0049c 13131 F102 F146 F102

値も変わっていないしフラグは同じで TEST っぽい。

しかし... ここでまた発見があった。 フラグレジスターのビット 12〜15 が必ず 1 だというのは、Intel のマニュアルにも書かれている話で、まったく問題ない。 問題はビット 1 で、80x86/80x87 ファミリー・テクニカルハンドブックという本には、8086 のフラグレジスターはビット 1 が 0 だよ、と書かれていたはずなのだが、今ここで見えているのは、Intel 80C88 のフラグレジスターはビット 1 が 1 ということだ。 はぁ。

じゃ、JX に積まれていた 8088 はどうだったか? というと、メモリーダンプを保存した時のデータが手元にあって、ディスケットに書き込むプログラムごとまるまる残っていたのでスタック領域もそこに含まれていた。 その中でそれっぽい値を見つけると、0xf246 というのがあった。Disk BIOS を呼び出した時のものだろうか、割り込み許可でゼロフラグが立っている、ありがちなやつだ。 さらに、BIOS の中で発生した割り込みらしき、0xf800 の手前に 0xf093 というのも残っている。 ビット 1 は立っていることになる。 意外と本もあてにならないよな...

2019/12/11 のコメントを読む・書く


12 (木)

%1 東京大学

仕事で某 Summit のため昼頃から東京大学へ。 学食に行ってみると昼間の時間帯は学生教職員優先で部外者は遠慮しろとある。 なかなか面倒な大学だ。 筑波大学ではそんなのなかったのに。 それで学外のカレー屋さんに入ってみるとなかなかよかった。

帰りはなんか途中駅で非常停止ボタンが扱われたとのことで駅間で非常停止があった以外は普通だった。 なんか、非常停止、体感でわかるな。 立っている人の一部がバランスを崩すほどの減速感、やや常用ブレーキより強く感じられる。 怪しいなと思っていると、緊急停止しますの自動音声アナウンス。 そこまで来てもボケッとしている人達は構えができておらず、停車寸前にばたばたとバランスを崩していく。 おいおい。 非常制動入ってたら運転士でもゆるめられないもんな。

%2 Portfolio

まだまだ undocumented instructions を試す。

fed050 00000000000000000000...

CALL AL? にあたる機械語、まさかの無限ループw こりゃなかなか難しいかな? まぁもうちょっと試そう。

31c0fed0 2A 0002 0366 F146 F1B8
31c0ffd0 2A 0002 0366 F146 01B8
31c0fee0 2A 0002 0366 F146
31c0ffe0 2A 0002 0366 F146

%ax をゼロクリアしてからの CALL AL, CALL AX, JMP AL, JMP AX 相当、なんか CALL AX と同じような挙動をしているように見える。 が... よく見るとスタックに差異があるな。 しかし 0 番地に cd 20 入ってないのかな? いやこれ割り込みのスタックか? 割り込みって TF クリアされるんじゃなかったっけ? まぁいいか。

31fffed7 2B F1B8
31ffffd7 2B 0002 0366 F146 01B8

%di で試そうとしたやつ。 よく考えたら %bl になっているような気がする。 全然違う結果になったなと思っていたがそのせいか。 しかし 01B8 のところが戻り番地のはずで、それが F1B8 と push されている。

50fef050 121 01B4 F1B4 01B4
50fef850 121 01B4 F1B4 01B4
31c0fef0 22 F100
31c048fef0 212 F1FF

PUSH AL にあたる機械語、1 バイト分だけスタックに積まれているように見えるw 上位 8 ビットが 0xf1 って何だろうと思っていたが、もしかしてこれ、TF 立てているから必ずスタックにフラグが残っていて、その上位 8 ビットが見えているだけかも。 もうちょっと試したいが、ま、いいや。 気分を変えて LEA AX,AX を試そう。

8dc050 21 FFF8
8dc150 21 FFF8
8dc851 21 FFF8
508dc050 121 FFF6 01B4
a100008dc050 321 FFF8

ふん、なんかどれもスタックポインターっぽいな。 もしかしてこれも TF のせいか? 試しに MOV SS を使ってみる。

8c1600018e1600018dc050 461 0100

ほぅ、0x100 が出てきた。 前の EA (Effective Address) がそのまま出てくるっぽい感じが... まぁありそうな話だが、そうなると TF クリアして試したほうがよさそう。

9c519da100008dc09d50 1118 0000 0000
9c519d90a100008dc09d9050 1119 0000
9c519d9001c88dc09d9050 1118 FFF6
9c519d90f6e48dc09d9050 1118 FFF6
9c519d90ac8dc09d9050 1117 0001
9c519d90ad8dc09d9050 1117 0002
9c519d90e2008dc09d9050 1117 FFF6

TF を消して試したいろいろ。 ちょっと POPF で面倒な感じになったので NOP を入れた。mov 0,%ax 後に LEA AX,AX すれば 0 が出てくる。 つまりクロック数計算に +EA が出てこない命令でも、メモリーアクセスで使ったっぽいアドレスが残っている。 レジスター同士の ADD 命令や MUL 命令では、変化しないらしくスタックのアドレスが残っている。 そして LODSB を試したら 1, LODSW を試したら 2 が出てくる。LOOP も試してみたらこれは変化はない。 何なのかというと、LODSB がアクセスしたのは 0 番地なのに、1 が出てくるってことは、LODSB の後の %si の更新で EA として残っているアドレスが変化するということ。 よくわかんないけど +EA のシステムと同じ計算機能を使っているのだろう。 それで LOOP も (フラグが変化しないので) EA を使うのかと一瞬思ったが、関係はないわけだ。

あとスタックポインターも POP の後、足した後の値が残っているのはおもしろいところ。8086/8088 が PUSH SP の際に 2 引いてから SP を書き込んで、POP SP の際は 2 足してから SP に書き込むので POP 前に戻ってしまうのは有名な話。 しかし 2 足した後の値が残るということは、POP 命令が BIU に SP のアドレスで読み取り要求を出してから、その結果をもらってレジスターに書き込む前までの間に、2 を足してレジスターに書き戻しているということか。

というわけでまたしても新発見をしてしまった。 残っている EA が読み取れるというのは、なんだかレジスターがひとつ増えたみたいで楽しい。

なお、全然別の Atari Portfolio の操作上の癖も発見した。Fn+O で電源をオフにするときは、Fn よりも O を先に離さないといけない。Fn を先に離すとその時点でオフになり、O を離した時にまた電源がオンになってしまう。

2019/12/12 のコメントを読む・書く


13 (金)

%1 きんようび

寒い日。

飯田橋と水道橋を勘違いして列車を降り、改札まで行ってから様子がおかしいなと思って調べて、また列車に乗り直すというあるある事例。 中央線の各駅停車 (中央総武線) の駅だということはわかるが、水道橋、飯田橋、市ヶ谷、あたりの位置関係はどうもあやふやな感じ。

%2 Portfolio

9c519d905159fef0589d9050 1119 00B4

フーン。 上位 8 ビットは前の値が残っている様子だから、やはりこれは、下位 8 ビットしか書き込まない PUSH 命令か。fef0 で push %al (?) ということ。

9c519d90fef4589d9050 1117 F001

ちゃんと push %ah (?) もできる。 例によって fefc にしても同じ挙動であった。JMP 命令や CALL 命令は挙動を調べるのが大変... せっかく TF で試すプログラム作ったんだからへんなところに飛んだ時の CS:IP を出すべきだった。 いや、それくらいなら簡単に試せそうだな。

2019/12/13 のコメントを読む・書く


14* (土)

%1 スクーター

スクーター (アドレス) の後輪ブレーキの戻りが悪い件の対策、先日に続いて再挑戦。 前カウルをすいすいと外し、メーターまわりをおそるおそる外したら何とかできた。 外してみてわかったが、ヘッドライトの向き調整用のねじは外さなくていいみたいだ。 方向指示器やヘッドライトはくっついたままでいい。

さて、カウルの裏にはママチャリみたいな金属製のハンドルが存在する。 スクーターのハンドルってこうなっていたのか。 確かに強度を考えると中まで全部プラスチックというわけにはいかないのだろう。 で、左側のブレーキレバーのところは、自転車なんかと同じようなものだ。 カバーを外し、ねじをゆるめ、ゆる、...、ゆるまない。 ウーン。 このねじをなめるわけにはいかないぞ...

それで、反対側のナットをゆるめようとしたら、方向指示器のスイッチの本体の部分が邪魔をしてソケットレンチが入らなさそう。 それで方向指示器のスイッチのねじをゆるめたが、あんまり動かせない。 ちゃんとスイッチを外さないといけないのか? とぐりぐりやっていた時、カウルがプラスチックなものだから、少し変形してソケットレンチが入りそうなことがわかった。 なるほどこうやるのか。 そんなわけで六角ナットは簡単にゆるみ、レバーを外すことができた。

そして、ブレーキワイヤーを、これどうやって外すんだっけな、と調べて、ずらしてワイヤーのところを合わせれば外れるのか、と理解して、何とか外せた。 引っ張られて作業しづらい時は、後輪タイヤ脇のブレーキを直接押し込めば多少マシになる。 で、ワイヤーに注油するのだが、手頃なオイルがないなと思って、とりあえずチェーンソーオイルを突っ込んでみたら、全然入っていかない。 ウーン。 何度も動かしながらちょっとずつ入れていったが、後輪タイヤ脇のブレーキを押し込みながらやるのはなかなか難しい作業である。 今思えばタイヤ脇のねじをゆるめてしまったほうが早かったな。

そんなこんなであんまり注油できた気がしないまま、手で動かしているとなんか多少軽くなっている気がした。 それでとりあえずワイヤーをはめ込み、レバーを元の位置に戻して、握ってみると、なるほど良好である。 ブレーキレバーに近い側がひどかったんだな。

それじゃ試運転だ、というわけで、ねじとカウル類を全部元に戻し (線を挟みそうになって焦った)、レバー位置の調整をしつつ出発。 良い。 かなり良い。 チェーンソーオイルを使ったのはちょっとアレだが、まぁいいか。 ジョルカブやジョルノなどと違って、アドレスの場合、ブレーキレバーのまわりまでカウルがガッツリある分、作業性はとことん悪いけれども、汚れの入りにくさという点では結構良いはずだし。 カウルだけでなく、ちゃんとブレーキレバーのねじの部分のゴムカバーまである。

%2 Portfolio

こないだのテストプログラムで lea 8(%bp), %sp のところの 8 を 2 に変えれば、フラグレジスターと CS:IP も見えるようになるので、バイナリーで書き換えて準備した。

JMP の前にまず PUSH 命令の確認。 バイト幅 PUSH にメモリーアドレスを指定してみた。0 番地には cd 20 が入っているのでそれを利用する。

fe360000 4 01B8 0366 F102 F1CD

メモリーアドレスの場合もやはり、SP は 2 引かれて、そこに 1 バイトだけ書き込まれる形のようだ。 それでは CALL 命令の確認。

fe160000 9 FFCD 0366 F102 F1B8

おっ? IP の下位 8 ビットしか書き込まれないのは PUSH 命令と同じだが、その後 IP が 0xffcd になっている。0xff はどこから出てきたのか? CALL FAR も試そう。

ff1e0000  20CD 16FE F102 01B8 0366
fe1e0000  FFCD FFFE F102 03B8 F166

上が通常の CALL FAR [0] で下がバイト幅の CALL FAR。 このコードに入ってくる直前の IRET 命令で使ったフラグレジスターの 0xf1xx と CS の 0x0366 が残っているはずと考えれば、CS:IP の書き込みもやはり下位 8 ビットしか書き込まれないようである。 そしてジャンプ先の上位 8 ビットが 0xff なのも同じで、セグメントもオフセットもそうなっているが、上と比較すると、ちゃんとセグメントがオフセット 2 から読み取られたらしいことがわかる。 読み取り長は 1 バイトにされてしまっているが、それ以外の SP の計算やダブルワードの読み取りでの 2 という数字はそのままなんだな。 さて 0xff とは...

81ec0001fe1e0000 4 FFCD FFFE F182 03BC F166 F206 F206 ...
8c1600018e160001fe1e0000 4 FFCD FFFE F102 03C0 F166

%sp を 0x100 引いてやることで、0xfe になるのでは、という期待を持っていたが、ならなかった。 また、0x100 番地を使って %ss に書き込んだ直後にすると 0x01 になるかも、という期待もあったが、ならなかった。 特に理由無く、単に 0xff になるのか。

さて、CALL FAR はすぐに止まってくれて実験しやすいので、もっとひねくれたことをしよう。CALL FAR AX はどうなる?

ffd8  0164 E000 F102 01B6 0366
fed8  0164 FF00 F102 03B6 F166
31c0ffd8 2 0164 E000 F146 01B8 0366
31c0fed8 2 0164 FF00 F146 03B8 F166
acffd8 1 0164 E000 F102 01B7 0366
acfed8 1 0164 FF00 F102 03B7 F166
ff36f8ff 4 01B8 0366 F102 24D7
ff36faff 4 01B8 0366 F102 E000
8c1600018e160001ffd8 4 0366 E801 F102 01BE 0366
8c1600018e160001fed8 4 0366 FF01 F102 03BE F166
1617ffd8 1 0164 E000 F102 01B8 0366
511617ffd8 11 0164 24D7 F102 01B9 0366 0004

どこから出てきた 0xe000, と思ったら見事にスタックポインター由来、いや、これは EA 由来だ。mov 0x100, %ss を入れたテストで 0xe801 の 0x01 はテストプログラムの最初の mov の最後のバイトで、0xe8 は次の call の最初のバイトなので、EA を見ていると言ってよさそう。 しかし最初の 0x0164 の由来がわからない。0xfff8 に書き込まれているのは 0x24d7 らしいし、%ax に入っているのは開始番地の 0x01b4 である。 いや、31c0 は xor %ax, %ax でつまり %ax を 0 にしても結果は変わらない。ffd9 など、違うレジスターを試しても結果は変わらなかった。

テストプログラムのバイナリーを見直すと、そうか、コード開始前とトラップのリターン前に書き込んでいる to のアドレスが 0x164 だ。 しかし EA はその後の pop と iret で変化しているはずだし、それだと mov 0x100, %ss の後だと 0x100 にならないとおかしいような? とにかく何らかのチャネルに残された値がそのまま出てきているということか? なんもわからん。

いや、ひょっとして、LES 命令でも同じことを試せる?

c4d85306 211 01B8 0366 F102 E000 F102
9c519dc4d88dc09d90530650 111711 01C0 0366 F102 FFF8 24D7 F006

んー? 違うのか... わからん...

ところで、関係ないけど LES 命令の後って割り込み禁止になるのかどうか。

c43f90 21 01B7 0366 F102

ならないみたいだ。

2019/12/14 のコメントを読む・書く


Powered by Tomsoft Diary System 1.7.4

/var/log/hdk.log コメント一覧

トップ / 日記索引 / 日記 (最新 5 日分)

Hideki EIRAKU