/var/log/hdk.log

2019 年 12 月下旬


20 (金)

%1 きんようび

テレビドラマ『結婚できない男』。2006 年のやつ。3 話まで見た。 なるほど、『まだ結婚できない男』と雰囲気はかなり似ている。 何より主要な登場人物が同じだし、同じ設定の人物がいる感じだ。 ほー。 折りたたみ式の携帯電話を登場人物が皆使っているのがちょっと懐かしい。 あと、高島礼子は同時期の『弁護士のくず』と両方出ていたんだな。

%2 Portfolio

CALL FAR 実験!

楽しい。 少し見えてきたんだけど、CALL FAR AX で出てきているオフセットアドレスは、計算だけでも変化するということは、ALU の入力側テンポラリーレジスターなのでは? それは 2 個あることになっていて、計算に使う入力値を置いておく場所のはずだが、その片方が見えているというならだいぶ納得できる話ではある。 以下はすべて想像だが...

そうすると調べるのは結構やっかいなんだけれども、おそらくは LEA AX,AX で出てきた EA は BIU 側のテンポラリーレジスターに保持されているものと見ていいと思うし、LES AX,AX の最後のメモリーアクセス結果というのも EA とは別に BIU 側のテンポラリーレジスターに保持されているのではないかと思うし、そしてスタックポインターの計算は BIU 側でできてしまうのか、あるいは、ALU に +2, -2 の演算機能があるとするならば、足す側のレジスターは使わずに演算が可能か。INC で変化しなかったから、INC 2 回的なことをやっていたとしても確かに変化しないことになる。 もし、EU が 8086 と 8088 で共通で、BIU が 16 ビットアクセスを 4+4 クロックですませられるということであれば、BIU 側で +1 の計算ができても不思議はなさそうな感じはしている。16 ビットアクセスしても EA に +1 のアドレスは残っていないしな。

そうそう、DOS のシェルの懐かしのコマンドライン入力操作、意外と覚えているもので、右矢印キー (または F1 キー) で直前のコマンドから 1 文字ずつ取り出し、左キーで 1 文字削除 (バックスペースと同等)、F3 で残り全部取り出し、Del キーで直前のコマンドを 1 文字削除、Ins キーで直前のコマンドに挿入するかどうかの切り替え、Esc キーで全部取り消し (\ が出て改行表示は大昔の UNIX の @ みたい)、的なやつ。Ins キーが最初きかない気がしていたが、Fn キーでちゃんと使えた。 なおファンクションキーは Fn を押して離してからの操作が可能だが、Ins キーとか電源オフ (O) とかはだめみたいだ。 他に F2 キーで直前コマンドから指定文字手前までまとめて取り出しもあったな。 細かいことは忘れたけど、この程度の雑な知識であとは触ってみればだいたいわかるもの。

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


21 (土)

%1 どようび

テレビドラマ『結婚できない男』、4〜6 話を見た。 この主人公は病院行きまくりだなw

テレビドラマ『弁護士のくず』、2〜4 話をまとめて見た。 各話 1/4 ずつぐらいは記憶にあったかな... オープニングで画面が微妙に小さいんだけど、これアナログ放送とディジタル放送が両方あった頃の番組なので、4:3 画面一杯に拡大しても問題なく話が理解できるようにしてあったんだな。 いや、この頃ってたぶん、16:9 では上下が少し切れていて、4:3 では左右が少し切れていたのかな。 『結婚できない男』もそうだな。

テレビドラマ『新米姉妹のふたりごはん』、またしても女同士でほんわか雰囲気のちょっと百合っぽさを醸し出していたがw 次が最終回ということで、これはやはりこのまま両親は出てこないのかな。

テレビドラマ『孤独のグルメ Season8』、こちらは最終回。 シンプルにカツ丼かと思ったら、冷し麻婆麺も食べてるw たくさん食べるよなーこの人w

テレビアニメ『歌舞伎町シャーロック』、最初の頃の話は 1 話ごと完結に近い感じだったが、最近は殺人事件の話でごちゃごちゃしていてなぞめいている。 まぁそれはいいとして、USB メモリーのことを「USB」「USB」と呼ぶのが気になるよねw まるでカップ麺をカップと呼ぶみたいで。

テレビアニメ『名探偵コナン』、珍しく 3 話構成だった。 しかし舞台で話をする小五郎おじさんはマイクを使っていたに違いないのに、コナンが眠らせて袖から変声機使ったらすぐわかるだろw

%2 Portfolio

TF テストプログラム修正版。 いろいろわかってきたので仕様を大幅に変えた。

さて。

さてさて。

ふむ。JMP FAR/LES/LEA で取り出せる 3 つの秘密のレジスターがあって、JMP FAR がレジスター間演算だけでも変化しうる危ういやつで、LEA はメモリーアクセスがあれば変化するし LEA 自身でも変化して、LES も LEA と同じくといったところか? いや、LEA だけだと LES の結果は変化なしか?

まぁそれで、どうやら EA 計算に ALU が使われていることもわかったわけだけど、即値の MOV など計算がいらない場合でもどうも一時的な置き場所として ALU の手前が使われているっぽいわけで、その使われ方を調べていくのはなかなか骨が折れる作業と思われる。 試しにかけ算割り算を...

MUL 命令で掛ける数が残っているのは意外、複雑な演算だから、テンポラリーレジスターフル活用しているかと思った。DIV 命令のほうはテンポラリーレジスターを活用していそうな雰囲気がある。

そうそう、Grp3 の 0, TEST の隣の 1 を一応試してみたらやはり TEST のようだった。 簡単なテストしかしていないけど。 あとはいかにも無視されそうな 0x8f と 0c6 と 0xc7 の 2 バイト目の真ん中、0xc7 は試していないけど、やはり無視されている。

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


22 (日)

%1 にちようび

朝からのどの調子がおかしい。 乾燥しすぎだったかな、といっても湿度 35% ぐらいはあったし、なんか変。 それで午前中はよく寝たのだが、昼になっても変。 軽い咳も出る。 ウーン。 体温は、15 時頃の時点では 36.8 度程度で、平熱っぽい感じだった。

それが、夕方ぐらいになるとさらに体調に変化が現れ始めた。18 時頃に測った体温は 37.2 度、体内で免疫系ががんばり始めている様子だ。 風邪か、いや、流行性感冒の可能性も高い。 職場でもらったとすれば感染者と同じ部屋にいたのは水曜日 (感染発覚がその翌日)、潜伏期間 4 日は少し長いかも知れないが、あり得ないほど長いわけでもない。 あるいは、木曜日は朝晩公共交通機関 (鉄道) を使ったし、ランチの店や弁当屋でもウイルス遭遇の機会はあったと言える。

夜 22 時頃になると軽い頭痛も感じられるようになった。 体温は変化がないが、咳が出ると頭痛が響くというのも多少つらい感じはする。 まぁ、流行性感冒の合併症のハイリスクの対象ではないはずだし、ひとまずゆっくり休む他ないだろう。 一晩で治ればまぁ普通感冒だろうねでいいけど、今のところ一晩で治る気はしないな。

午後は、体調が怪しいので、家でおとなしく、Lode Runner (1983) というビデオゲームで遊んでいた。https://archive.org/details/msdos_Lode_Runner_1983_1983 で遊べる。DOS 版あったんだな。 ちょっとスピードがおかしい感じがする。 ずーっと進めていくとレベル 80 までたどり着いた。 古いビデオゲームでルールはシンプルだが、適度な難しさで各レベルが作り込まれているのが市販ゲームらしい。 いくら古いとはいえ Broderbund もよく許可を出したな。 えっ? 許可はないんじゃないかって? いやいや、まさかそんな...

%2 Portfolio

ふと思いついて WAIT と HLT を再び。TF と IF を同時に 1 にして実験。

たぶんだけど WAIT は配線がされていなくて永遠に終わらないのだと思うが、この命令、割り込み許可であれば割り込みを受け付けるんだな。 で、POPF で TF=1 にしたら、その直後の命令ではシングルステップがまだ起動しないから、WAIT も HLT も、静かに割り込みを待つ形。 いやまぁ、WAIT は WAIT 信号 (?) を待つんだけど、割り込みがあれば割り込みが処理されるので。 で、割り込みの時には REP と同様、バイト数固定で IP を引くようだ。 これはもう 8086/8088 の実装上どうしようもないんだろうな。 たぶん元の IP はどこにも残されていないんだと思う。80286 以降だと、一般保護例外みたいに問題を起こした命令から進まないままの例外というのが存在するけど、8086/8088 の頃はなかったんだから。 除算例外でさえも次の命令に進んでから発生するらしいし。

備忘録としてこれまでにわかった割り込み受付の挙動をまとめて擬似コードっぽくしておきたいのだが、なかなかうまく書けない。HLT/WAIT/REP ***S* は皆、内部で繰り返しつつ、割り込みが来たら次に進んだり中断したりする命令だ。 なので、命令を実行してから割り込みをチェックする、みたいなシンプルな話にはならないんだ。 それに加えて TF やら IF やらの遅延の挙動、もうカオスである。

優先度的にはゼロ除算やソフトウェア割り込みなど命令が原因のものが一番優先度が高いらしくて、その次が NMI, その次が外部割り込みで、最後にシングルステップらしい。 しかしシングルステップは IF が無関係なのと、TF=0 に変化していても命令の実行前の値が反映されてしまう特徴があるので、優先度の高い割り込みのハンドラーの入口でシングルステップ発動というのがあるわけだ。 で、そうやって考えていくと、最悪パターンはソフトウェア割り込みと NMI とシングルステップが同時に処理されるケースでは? NMI を好きな時に投入できる PCjr/JX みたいなマシンか、自分で組んだボードでも使わない限り試しようがないけど、3 つ同時、きっとあるんだろうなぁ。PCjr/JX でどうやって試せばいいかと言うと、セグメントレジスターへの MOV を 64KB 分埋めて、最後に INT 命令を入れて、その入口に TF=1 で IRET するので OK だと思う。 セグメントレジスターへの MOV の間は NMI も発生しないから、かなりの時間稼ぎができる。 その間にキーボードをたたけば NMI も、というわけだ。 まぁ、ポート A0 を使う手もありそうだけど。

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


23 (月)

%1 上皇誕生日

平成元年に小学校入学した世代の自分には、祝日じゃない 12 月 23 日は記憶になく、ほとんど初めてみたいなもので違和感がある。

きのう、一晩で治る気はしないと書いた風邪の諸症状。 未明の 4 時頃体温が 36.8 度くらいで、今朝 8 時頃には 36.5 度まで下がっていた。 頭痛も解消して、気分もすっきりしていて、咳が少し出るのとのどが変なだけ、みたいな感じ。 微熱が一晩で引くとは、これは流行性感冒じゃなさそうだな。 高熱が出るのを覚悟していたから、いい意味で予想外だった。 でもなんか、夜やたら眠くなるのはやっぱり回復途上なのかな。

%2 8088

どうやったら命令クロック数の計測ができるかな。 ぱっと思いつくのは、違いがわかるくらいの回数繰り返す方法だ。5MHz なら、5M 回実行すれば、1 クロック差が 1 秒になる、という具合だ。 プリフェッチの影響には注意が必要だけど、CL 指定のシフト命令や AAM/AAD 命令などで調整する手もある。

しかし... 例えばかけ算命令の掛ける数の違いによる実行時間の差を見たいとすると、かけ算 1 回で 100 クロックばかり使うわけで、5M 回が 500M クロック... 100 秒もの時間になる。 つまり 100 秒なのか 101 秒なのかで差を見ることになる。 まぁ、できなくはなさそうだけど、電池が一気に消耗しそうだな。 あと動画撮影でもしておかないと、目視でストップウォッチ操作はつらいところだ。Portfolio だと内蔵時計は秒単位っぽいので、プログラムで計測するのは厳しそうかな。

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


24 (火)

%1 かようび

耳鼻科。 いつものに加えて風邪っぽい症状であることを伝えた。 流行性感冒でも熱が出ない人もいるらしいのだが、熱は出なくても全身だるーい感じにはなるらしい。 自分は熱が出ていないだけでなく、全身だるいとか痛いとかいう症状もないので、風邪でしょう、と。 のどの違和感と軽い咳だけだったら薬もいらないですねー、って感じで。

そんな感じだったんだけど、夕方ぐらいから軽い頭痛がしてちょっと咳も出ている。 咳はだいたいなんともなさそうに見えて、突然げほっと出たかと思うと立て続けにげほげほげほ、となるやつ。 まぁ、まだ治っていないんだろうな、という感じ。 引き続き無理はしないようにしよう。 なお、職場では流行性感冒に感染した人が 1 人増えていた。 流行っているなぁ。 風邪は流行るし、外は北風で原付のスピードでもめちゃくちゃ寒いし、自然は厳しい。

%2 Portfolio

そういえば JMP の 8 ビットレジスター指定をちゃんと試していなかった。 今のテストプログラムなら、シングルステップで IP が大小関係なく範囲外になった時点で終了するので非常に試しやすい。

これは... AL, CL, DL, BL に対してはそれぞれ AX, CX, DX, BX 指定と同じになり、AH, CH, DH, BH に対してはそれぞれ、AX, CX, DX, BX を 8 ビットローテートした値と同じになっている。 へぇ! そういえば、ディスティネーションが 16 ビットでソースが不正に 8 ビットにできる命令って JMP と CALL くらいだよな。 しかし、上位 8 ビットを下位 8 ビットに持ってくるのは理解できるけど、下位 8 ビットを上位 8 ビットに持ってくるのって、アキュームレーター以外は用途なくない? なんでわざわざそんな配線を持っているのだろうか? いや... AA*/DA*/*AHF などの用途を考えたけど、アキュームレーターだけ持たせても、入力側と出力側がそれぞれ必要になるのだろうし、セレクターに持たせたとしても配線量は一緒か。 そうすると仕組み上は残りの SP, BP, SI, DI も上下 8 ビットの入れ替えができるのかも知れないな、機械語で表現できないだけで。

さて、調べてみると Portfolio の BIOS には INT 61H でメロディートーンをならす機能があって、長さは 10ms 単位で指定するらしい。 ほう? どうやって待っているのか? まさかビジーウェイトか? 割り込みは許可っぽいが。 何とかして調べてみるしかないな! あるいは、clock tick speed の変更ができるらしいので、これを 1 秒ごとに変えれば命令実行時間の計測に役立つかも。1 秒間に何回実行できたかを計測できるので。

というわけで、clock tick speed を変えて、1 秒あたりの実行回数を数える簡単なプログラムをとりあえず作った。 これ、int $0x61 をコメントアウトすれば PC 互換機でも動くはずだが、dosemu のエミュレーションはバグっててクラッシュするので注意。Portfolio では、90 で 7E05, 9090 で 32F6 か 32F5 が出てきて、40 だと 7E05。 思ったより安定した数字が出る。90 と 40 の差がないのはジャンプでプリフェッチキューが消えているためだろう。90 も 40 もフェッチ待ちより短い実行時間な命令だからな。 フェッチ待ちがどれだけかは最速 4 クロックってだけで想像だけど、Portfolio はスタティック RAM を使っているのでシンプルに 4 クロックだろうと思っている。VRAM もリフレッシュを別途やらないと書き換えただけでは画面は更新されないらしいので。

もう少し試すか。b10dd50a - mov $0xd, %cl; aad で、D982。b10dd3c0 - mov $0xd, %cl; rol %cl, %ax でも、D982。 これは狙い通り。AAD 命令は値によらず一定のクロック数だそうなので、それにぴったり一致する別の命令を入れても同じになるのは当然。 わざとローテートするビット数を変えれば、例えば b10cd3c0 とすれば E3DD ぐらいになるし、b10ed3c0 とすれば D00D になる。 これが 4 クロックの差。 このくらいの精度なら、1 クロックの差も見えそうだな。 長時間かかる命令と、それに実行時間が近いであろうシフト命令を用意すれば比較ができそう。 とりあえずかけ算だけの簡単な実験では、b80000f6e4 で BBA7, b80100f6e4 で B9D5, b8ff00f6e4 で AE02, b80001f6e4 では BBA7 と、%al の 1 のビットの数で実行時間が変わることが確認できた。 あれ? ひょっとして... b10dd501 とすると速くなるのか? ...DC02 だ! AAD 命令も実は (かつては undocumented だった) オペランドの値の 1 のビットの数が重要なんだな! 逆に 4 ビット増やして b10dd5fa とすれば D00D となり、ちょうど上のビット数を増やしたローテートと一致する。 いいね。

というわけで、クロック数でも遊んでいきたい。

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


25 (水)

%1 すいようび

整形外科。1 週間ほど行っていなかったが、未明にややつらめな神経痛が出たので。

風邪の諸症状は変わらず、いや、きのうよりはややいいかな。

%2 Portfolio

かけ算命令のまた簡単なところからやってみよう。 きのうの実験から、8 ビットのレジスター同士の符号無しかけ算は、70〜77 クロックで、%al の 1 のビットの数が影響するので間違いなさそうだ。16 ビットだと 118〜133 クロックということになっているが、果たして。 比較用は 28 ビットシフトで 120 クロックというのを使おう。

うむ、予想通り %ax の 1 のビット数が影響するようだ。 実にシンプル、なのはいいけど、8086/8088 の ALU は 16 ビットでできていると思うので、中がどうなっているのか、おもしろいところではある。 いや。もうちょっと試すか。

ほーん、なんか微妙に最適化というか、打ち切り処理的なものが入っているんだな。 ここでは %ax 掛ける %bx なので、%ax の 1 のビットの位置に %bx を合わせて足す、という動作だが、えっ、いや待てよ、%bx が 0 の時より値が入っている時のほうが速い、というのは... やばいな、また難しいのを見つけてしまった...

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


26 (木)

%1 もくようび

風邪なんだけど、そういえば、きのうの朝は少し汗をかく感じで目が覚めたんだった。 そして今日は日中さらに回復した感じ。 まぁたまに咳は出るけど、それ以外で体調が悪い感じはほぼなくなった。

テレビドラマ『結婚できない男』、ほんと、どの話もノリが同じだな。 いちおう新しい小ネタを混ぜてくるけど、最終的な結果は同じ、みたいな、このマンネリ感がいいんだろうな。 すげぇ気軽に見られる。

%2 Portfolio

きのうのやつ、もしかしてオーバーフロー絡みではないか。8 ビットのかけ算をもう一度やってみる。

ということで... MUL 命令は上位側が 0 以外になると OF と CF をセットする機能があるが、そのセットされる時のほうが 1 クロック短いんだな。 きのうの 16 ビットも同じパターンのように見える。0 を掛けるとオーバーフローはしないので、70〜77 クロックとか 118〜133 クロックとか、その範囲は外れないけど。IMUL も見てみるか。80〜98 クロックのはず。

えーっと、こんな感じでいろいろと試した結果、どうやら中で符号反転をして計算しているらしいことが推測できた。 正掛ける正は MUL と同じ形。 負掛ける負は正掛ける正の +1 クロックで予想以上に高速である。 いや、そこに、MUL の時と同様に、OF および CF がセットされるケース (★) については -1 クロックというのがあるようである。 なお、そのケースは 8 ビットで表現できるかどうか、で、つまり上位が下位を符号拡張した内容になるかどうかとなっている。 で、オペランドだけが負の時が次に遅く 91〜、アキュームレーターだけが負の時は最高に遅く 95〜、らしい。

まぁ、符号ありかけ算が符号無しと同じように実現できるのは入力と出力のビット数が同じ場合だけで、IMUL 命令では違うわけだから、別にそのアルゴリズム自体はいいんだが、最大 101 クロックというのは気にくわない... 80〜98 じゃなかったのかよ! どの本にも載っていなかった事実... 長年だまされていたぞw

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


27 (金)

%1 仕事納め

大掃除、仕事納め、納会。

%2 Portfolio

なんとなく、8086/8088 のかけ算のアルゴリズムが見えてきた気がする。

かけ算のアルゴリズム (0200〜)

この 0200〜は 8 ビットの MUL AH と同じ AX を返すサブルーチンを MUL なしで実装したものである。0100〜は比較用の実験コード。 味噌はループ用の CX を除けば AL と AH とテンポラリーに DL しか使っていない点で、16 ビットも AX と DX とテンポラリーの 16 ビットがあれば行ける。 シフトをローテートと組み合わせて 2 命令にすることになるけど、例の 8086/8088 の構成図にあるレジスターと ALU だけで十分実現できそう。 固定回数ループについてはたぶん、EU の中で何とかできるんだと思う。

で。 そうすると ALU の入力側のテンポラリーレジスターに、MUL のオペランドの中身が入って、それは最後までそのままになる。 まぁ、実際、JMP FAR AX で取り出せるのがその値なわけ。 そういえば 8 ビットだとどうなるんだっけな。

フーン。 例によって上下ひっくり返るアレだ。 ま、いいや。IMUL 命令だとどうなるかな?

0 だ... 符号絡みの処理で 0 になるのかな... ま、じゃあ、次は MUL 命令でフラグレジスターを見てみる。CF と OF は仕様にある通りなので、未定義の AF, PF, SF と ZF について。

SF, ZF と PF については予想通りだった。 上に書いたプログラムと同じように、最後に AH (おそらく 16 ビットでは DX) の内容が反映される。 しかし AF は違うみたいだ。AF は足し算引き算におけるビット 0〜3 のキャリーを表すのだが、ここでは常に 0 か? 最後が足し算じゃなくて、論理演算か? いや、足し算じゃないと上のプログラムは動かない。 例えば %ax=0xff81 の例はそうで、最後は 0x7f80+0xff を計算して、0x807f になるので、AF=1 になるところ、実際の MUL 命令の結果では AF=0 になっている。 ウーン? まぁエミュレーター的には単に AF=0 にすればいいのかなー? (そもそも仕様外なところまで合わせる意味はあまりない)

あと、ちょっと割り算の話。IDIV 命令は負の最小値を範囲外扱いでエラーにしてしまうという。

本当だ!

つまりだ、アレ、IMUL 命令では AF=1 になっているな? まぁいいとして、とにかくだ、-128 に 1 掛けて 1 で割ろう、とすると、IMUL 命令は -128 が答えに出た時に CF も OF もクリアしているのに、1 で割った時には除算エラーになる、というおもしろ現象である。 っていうかそうか、かけ算がある程度わかったところで割り算アルゴリズムも気になりだしたんだけど、IMUL 命令のフラグレジスターもなかなか難しそうだな。

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


28 (土)

%1 どようび

Google Maps を見てみたところ、都内の道は空いているようだ。 というわけで飯能まで行ってみたが、そこまで空いているというわけではなかった。 まぁ、混雑はしていない、程度。 この季節らしく、なぜか急ぎすぎている人やら、なぜかのんびりしすぎている人やらいるので、安全運転でね。

そんなわけでレンタルカート。 飯能。4 回乗ってベストタイムは 33.825 秒ぐらい。7 コーナーは、コーナリングスピードを稼ぐより、距離重視できゅっと曲げてドーンと加速したほうが速いよという、超速い人の貴重なアドバイスをいただいた。 いわんとすることはわずかにわかるような気はする。 極端な話、間違って後輪を一瞬ロックさせてしまっても、うまく向きが変わって加速できるとタイムはそんなには落ちないというのがある。 逆にタイヤのグリップをうまく使えたと思っても、加速していかないケースがあるのもなんとなく理解できる。 あと、以前スタッフさんもおっしゃっていたことだが、早い段階でアクセルを踏み始めることで挙動が乱れにくくなるはずなのに、自分はそれができていない。 パーシャルスロットルに関しては以前よりかなり使うようになったが、7 コーナーでの操作のタイミングは相変わらず難しい。

そうそう、今日は青梅 IC 側のルートで行ったけど、こないだのパトカーが駐まっていた成木のところ、あれ殺人事件があったところの近くだったのね。 後でニュースで知った。 たぶんだけど、現場付近を通行止めにしていて、あの交差点で、現場手前までに用事がある人は通して、現場より先に用事がある人には迂回するよう案内していたんだろう。 交通事故にしてはなんだか様子が変だなーとは思ったが、まさか殺人事件だったとは。

%2 除算命令

割り算アルゴリズム
割り算アルゴリズムテストコード

きのうのかけ算のノリで 16 ビット割る 8 ビットの割り算も書いてみた。 エラーチェック無し。 最初適当に書いたら商が 1 ビットズレていて、それはすぐに直して、よさそうだなと思ってテストコードを走らせたら、0x100/0x81 が商 0 になってしまった。 おかしいなと考え直して、0205 の条件ジャンプを追加したら解決。8 ビット同士の比較では 0x100 との比較はできないから、シフトでビットがあふれたらもう大小関係は確定、みたいな処理になる。 さらにコードを整理して上のように短くなった。 これなら 16 ビットも同じやり方で行ける。

さて... このコードはエラーチェック無しなので、0 除算とか、商が 8 ビットにおさまらない場合とかでも、そのまま実行できる。 どんな結果になるだろうか? 「商...余り」の形で示す。

ふむ。0 除算は商が全ビット 1 になり、余りが割られる数の下位ビットになる。 まぁこれは比較的わかりやすい。0 より小さくなることはないからだ。 しかし、桁がおさまらないほうは様々だ。 除算で例外が発生しないプロセッサを作るとすれば、こういう挙動になるものもあるだろうけど、仕様上は未定義とすることになるだろう。

で。8086/8088 が除算エラー割り込みを作った理由を想像する。 このエラーチェックは一番最初に行える。 最初のシフトの前に大小比較、上のプログラムで言えば CMP AH,DL を最初にやればいい。 それでキャリーがなければエラー。0 除算もシンプルにこれだけで排除できる。 符号付きのほうもおそらく、-128 がエラー扱いになることからして、符号反転して正の数にした後、最上位ビットまで 2 回分を比較すれば、桁あふれはチェックできる。 しかし、ただでも遅い除算命令が、このチェックのためにさらに遅くなっているとも考えられる。 そこまでして何でチェックを入れたのだろうか? 8080 には除算命令は無かったらしいので、8080 の互換のためではない。 こうしてみると... 未定義の答えが出る命令というのを排除したかったのではないか。 加減算は符号付きかどうかにかかわらず同じ命令を使うので、桁あふれはあり得るが、未定義にはならない。 乗算命令は答えのビット数が倍なので、AAD 命令を除いて桁あふれすら存在しない。 つまり、8086/8088 の命令セットでは、除算命令さえ何とかなれば、結果が未定義になる命令はなくなる。(ただし、フラグレジスターの結果には未定義が存在する。)

ところで... 内部のレジスターの構成から考えると、もしかして、除算エラー時には汎用レジスターの内容は変更されているのではないか? Portfolio で実験してみる。 例の TF 実験プログラムで簡単に調べられる... いや、レジスターの内容を勝手にはダンプしないんだった。 ふむむ。

これで %dx と %ax が見られるが、結果、変化していなさそうだ。 ふーん。 詳細はわからんなぁ。

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


29 (日)

%1 にちようび

ちょっと外の掃除をした。

テレビドラマ『女王の教室』、2005 年に見たやつだけど、なんか今 TVer で見られるのがあるので見てみた。 懐かしい。 このときの子役達の中に今も普通に俳優をしている人は何人もいるようで、なんか大人の俳優として見たような顔がいるなぁと調べてみたが名前がわからなかった。 子役でも脇役は名前がわからないやつw

%2 Portfolio

今更ながら、Atari キーと E キーでテキストエディターが起動するというショートカットを発見した。 キーボードにちゃんと書いてある。

MUL 命令の結果の未定義のフラグレジスターを 8 ビットに関して全部確認する。

すべての組み合わせについて一致した。OK。

さて、ちょっと AAA 命令について試した。

フーン。 フラグがよくわからん。 気分を変えてクロック数推定をしよう。

短いクロック数の推定は難しいな。 実行時間の長い AAD 命令でプリフェッチキューを埋めれば見えるかと思ったが、どうもうまく出ている感じじゃない。AAD 命令で挟んでみるか。

これならまぁまぁだな。 やっぱりシフト系命令は最短 2 バイトの癖に最短 2 クロックなんだな。 プリフェッチキューが消えるジャンプ命令はちょっと難しいか。 この中では ADD 命令で +EA が違って 17 クロックになるはずのところだけ謎だ。LEA 命令ならちゃんと 9 クロックと 10 クロックで +EA の差が見えたのに。 他がメモリーアクセスを伴ってもやたら精度良く見えているだけに... (Portfolio はスタティック RAM なので、メモリーアクセスはおそらく最短時間の 4 クロックで済んでいるようで、計算しやすい。)

9 日に電池交換してから、こんなにいろいろ遊んでもまだ電池が切れない Portfolio, やはりなかなかの出来。 これにもし日本語サポートがあったら日本でも売れていただろうなぁ、と思うけど、メモリーの少なさと画面の狭さから、日本語対応しようと思ったら結構苦労しただろうな、とも思う。1990 年代に DOS/V が出てきて、ソフトウェアによる日本語表示が実用的になったのは、やっぱり 32 ビット CPU の存在は大きかったみたいなのだ。80C88 な Portfolio だと、拡張カードで何とかせざるを得なかっただろうな。 それでも画面の狭さはどうにもならないけど。

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


30 (月)

%1 冬休み 1 日目

のんびりした日。 曇り時々雨。

%2 Portfolio

きのうの続き。 試しに CL 指定のシフト命令を入れたところこんな結果が得られた。

数字がだんだん変わっていくのは、CL の値が 8 から 1 まで変化しているため。 それで、シフト命令 (ローテートだけど) のクロック数としては 40 クロックから 4 ずつ減って 12 クロックまで変化しているはずである。 ところが、きのうの計算と見比べると 1 クロック違う。 例えば 7D1A は 12 クロックのはずだが、きのうの aaa; nop の 11 クロックと一致してしまっている。 なんだかよくわからないけど、add (%bx,%di),%al で起きた謎はこのへんも関係がありそうだな。 あっ、きのうの 10 と 11 の間の差が少し大きいな。 もしかして...

フーン、なんもわからん... まぁこれはおいておくとして、いろんな命令での ALU のところのテンポラリーレジスターの使用状況を調べた。 単なるレジスター間 MOV 命令でも変化するが、MOVS/STOS/LODS 命令では変化しない。 アキュームレーターに対するメモリーアドレス直接指定の MOV 命令でも、残るのはメモリーのアドレスで、中身は残らない。 とするとアキュームレーターについては BIU 側と直接やりとりできる経路があるっぽい? いや、セグメントレジスターと汎用レジスターの間の MOV 命令でも変化しないんだよな。EU 内で完結するやりとりで使用されるのか。

ストリング命令による %si/%di の演算は ALU を使っていないのではないかと思う。PUSH/POP 命令やリターン命令の %sp も同様。 しかし RET/RETF 命令の即値引数を使った場合は、足す前の %sp の値が残るので、ALU を使っているように見える。 つまり 1 や 2 を足したり引いたりするだけなら BIU 側で行える、ということではないかと見ている。IP の足し算も必要だしな。

シフトの CL 指定はシフト後の値が残るみたいだが、8 ビットローテート時に上位 8 ビットも動いているみたいでもう少し調査が必要。 なお各種割り込み命令後はジャンプ先の IP の中身が残るみたいで、おかしいな、IP は BIU 側が持っているはずだから別に EU 側に持ってこなくてもいいと思うんだが...

4 日にプリフェッチキューのことを少し調べていたが、あらためて振り返ってみた。 きのうのクロック数推定の謎を解くためにも、そのあたりの知識が必要そうだし。 以前図書館で借りた本に長い例があって、インターネットで見つけたマニュアルにも英語で同じものがあったけど、やはり、1 バイトに 1 クロックサイクルは使っているように見える。 そうすると 2 バイトの MOV CS 命令の途中で CS が変わっているというのはおかしい。 そこで、プリフェッチが 1 クロック遅れて始まると仮定すると、MOV CS 命令の途中で CS が変わることがなくなり、一応先日の話との整合性は保てるような気がする。1 クロック遅れて始まるというのも理解できるところはあって、プリフェッチキューから取り出した 1 バイトを元に順序回路の次の値を準備する、その間はまだキューに残っているから次のフェッチは開始できない、というのはまぁ、ありそうかな、みたいな。 ただ、シフト命令が 2 バイト 2 クロックなのがどうも納得しづらいところがあるが、まぁいいか...

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


31 (火)

%1 冬休み 2 日目

昼間は暖かかったが、夕方頃から北風が吹きすさみ急に冷え込んできた日。

今年は新しいディジタルカメラを買ったわけだが、そういえばまだそれで三脚を使ったことが無かった。10 年近くも前に、ドンキホーテでわずか 1280 円で買った三脚を持っていて、しばらく使っていなかったが、使えるはずだと思って出してみたら、プラスチックのパーツがポキッと... 壊れてしまった。 アチャー。 それで、ビックカメラに行ってみたら、三脚だけでピンからキリまで、数千円から数万円のものまで勢揃いである。4000 円ぐらいの、定価の半額ぐらいの少し頑丈そうなやつを見つけて、いいかなと思ったが、在庫はありになっているのに見当たらないということで、おそらく誰かが買おうとして持って店内にいるのだろうとのこと。 こういうの、在庫があれば勢いで買っちゃうんだけどな、ないって言われるとそうですか、って終わっちゃうやつ。 まぁしかしとにかく選択肢がおそろしく豊富なことはわかった。

夜は兄者とめし。 そろそろ給油しなきゃと思ってスクーターで行ったら寒いのなんの。 大晦日の夜だけど店の混雑はまぁそれほどでもない感じ。 そば屋じゃないしな。 それより帰り道のガラガラっぷりが大晦日だったw 普段なら 19 時台にこんなに空いているわけがない。 深夜か早朝か、というくらいガラガラだった。

紅白歌合戦はラジオで途中から適当に。

%2 スクーター

アドレス V100 タイプ S, 前のオーナーにより方向指示器が LED 化されている。 これ、点滅時に車幅灯みたいに薄く光るので本当はだめなやつじゃないかと思う。 それはともかく、先日まで点滅間隔が短くなっていることがあった。 球切れを起こした時のようで、一応確認したが点滅が変なだけで光ってはいた。 急に間隔が正常になることもあり、電圧の問題かと思ったがエンジン回転数を上げてもだめな時はだめで、LED 絡みの制御回路の不良か何かか、なんだろうなと思っていた。

で、この前のブレーキワイヤー注油の際に、ついでに、方向指示器のスイッチに何気なく注油した。 こういうのには本当は良くないと言われる KURE CRC 5-56 を、さらっと、ちょろっとさしただけ。 そうしたら、方向指示器の点滅間隔が短くなることはなくなった。 例えばオートチョークのコネクターのほうはその後も何度か怪しくなっているが、オートチョークが戻らずアイドリングが低く不安定になっている時でさえも、方向指示器の点滅間隔は短くはならない。

つまり? 制御回路なんかの問題ではなくて、ただ単にスイッチの接点の抵抗が大きくなっていただけだと思う。5-56 は接点復活剤としても機能するので、抵抗値が元に戻ったのである。 なんか、灯台もと暗しというか、そこに接点があって、直列で方向指示器の回路があるはずというのは言われてみればそうなんだけど、思考がディジタルに侵されていて、トランジスターみたいなものでスイッチングしている感覚というか、まぁその...

%3 Portfolio

MOV CS 実験の改良版。 他の実験プログラムと同じようにコマンドライン引数から入力するように変更したのと、%dl をぶっ壊してもいいように変更したので cwtd が使えるようになった。%bx は引き続き壊しちゃだめだが、その %bx を使って数えるようにしてある。

さて、cwtd は 5 クロックなので結構微妙なところが見られるかなと期待している。

えぇー? MOV CS が 2 バイトなので、99999999 で 2 になっているところは、MOV CS の次の 1 バイトも含めた 7 バイト分を MOV CS の完了までにフェッチして、しかもその次の 1 バイトのフェッチも始めている計算。 最初の 1 バイトはフェッチが済まないと実行できないから無視するとして、残りの 6 バイトのフェッチをすませるには 24 クロック必要。 でも 20 クロックと MOV CS の 2 クロックとなると足りない。 あれれれれ?

そんなはずはないけど cwtd が 6 クロックだと計算は合う。 どの資料も cwtd (CWD) は 5 クロックになっているからそんな間違いがあるはずはないけど。 そもそも 37273740 と 37274037 で差があるのもアレだ。

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


Powered by Tomsoft Diary System 1.7.4

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

トップ / 日記索引 / 日記 (2019 年 12 月下旬)

Hideki EIRAKU