マシン語を始めた時
2024.11.27
確か高校生になってからマシン語の勉強を始めた。(Z80)
図書館でMSX用のマシン語の本を借りてきて、まずは画面にAという文字を表示させてみた。
次にループを作って、これを画面いっぱいに表示させてみてBASICと比べてみたらどうか。当たり前だけどBASICより速い。一瞬で出た。こんなに速いんだ、と。
こんなところからのスタートでした。
何を作ろうという目標はなかったけど、たとえば結果が画面に出るのはわかりやすかった。
マシン語に詳しい同級生から色々指導を受けた事もある。
たとえば、グラフィック画面を白黒反転するプログラムを作れ、とか。
画面の指定した範囲を、行き先の座標を指定して移動させろ、とか。
持ち帰って考えてみて、わからなかったら翌日聞いてみて、ああ、こんなふうにすればよかったのか、と。
そもそも最初はループを作るにはどうしたらいいか、というレベル。
DJNZはわかった。
でもグラフィックだったらアドレス空間だから8bitのDJNZでは足りない。16ビットのカウントはどうしたらよいか。
LD HL,0C000H
LD BC,02000H
LOOP:
LD A,(HL)
CPL
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,LOOP
たとえば、こんなふうに書く。
OR C とか JR NZ, なんかは最初わからなかった。
フラグというものを利用する。
たとえば計算結果がゼロになったらZフラグが立つ。
ゼロか、ゼロでないか、という判断ができる。
そのほかに、キャリーというフラグもある。
上記では、BもCもゼロになるまでループするわけだ。つまり、2000H回繰り返す。
それなら、BとCを直接ORすればいいのにという疑問が出てくるけど、そういう命令はZ80には存在しない。Aと他のレジスタとの演算になるので、Bを一旦Aに入れてからCとORして、その結果のフラグを見る。
結果ゼロでなければ(NZ:ノンゼロ) LOOPへジャンプする。
プログラムの最後もきちんとしないといけない。たとえばBASICから呼び出しているならRETにするだろう。
何らかの止める命令を入れておかないと、これ以後も命令を実行し続けてしまい暴走する。
止めて良いならHALTとか、STOP: JR STOP のようにする。
JR命令は相対アドレスのジャンプ命令で、ハンドアセンブルの時はFF FE FD FC FB FA...と逆方向にジャンプ先まで数えていた。
絶対アドレスでも良いけど、1バイト増える。もったいない。(という考え方があった)
図書館でMSX用のマシン語の本を借りてきて、まずは画面にAという文字を表示させてみた。
次にループを作って、これを画面いっぱいに表示させてみてBASICと比べてみたらどうか。当たり前だけどBASICより速い。一瞬で出た。こんなに速いんだ、と。
こんなところからのスタートでした。
何を作ろうという目標はなかったけど、たとえば結果が画面に出るのはわかりやすかった。
マシン語に詳しい同級生から色々指導を受けた事もある。
たとえば、グラフィック画面を白黒反転するプログラムを作れ、とか。
画面の指定した範囲を、行き先の座標を指定して移動させろ、とか。
持ち帰って考えてみて、わからなかったら翌日聞いてみて、ああ、こんなふうにすればよかったのか、と。
そもそも最初はループを作るにはどうしたらいいか、というレベル。
DJNZはわかった。
でもグラフィックだったらアドレス空間だから8bitのDJNZでは足りない。16ビットのカウントはどうしたらよいか。
LD HL,0C000H
LD BC,02000H
LOOP:
LD A,(HL)
CPL
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,LOOP
たとえば、こんなふうに書く。
OR C とか JR NZ, なんかは最初わからなかった。
フラグというものを利用する。
たとえば計算結果がゼロになったらZフラグが立つ。
ゼロか、ゼロでないか、という判断ができる。
そのほかに、キャリーというフラグもある。
上記では、BもCもゼロになるまでループするわけだ。つまり、2000H回繰り返す。
それなら、BとCを直接ORすればいいのにという疑問が出てくるけど、そういう命令はZ80には存在しない。Aと他のレジスタとの演算になるので、Bを一旦Aに入れてからCとORして、その結果のフラグを見る。
結果ゼロでなければ(NZ:ノンゼロ) LOOPへジャンプする。
プログラムの最後もきちんとしないといけない。たとえばBASICから呼び出しているならRETにするだろう。
何らかの止める命令を入れておかないと、これ以後も命令を実行し続けてしまい暴走する。
止めて良いならHALTとか、STOP: JR STOP のようにする。
JR命令は相対アドレスのジャンプ命令で、ハンドアセンブルの時はFF FE FD FC FB FA...と逆方向にジャンプ先まで数えていた。
絶対アドレスでも良いけど、1バイト増える。もったいない。(という考え方があった)
逆アセンブラ
2024.11.27
逆アセンブラ とは、バイナリ(マシン語)からニーモニックに変換するプログラム。
たとえばROMの内容を読み出して、ソースを再現したり解析したりする時に使う。
今ではネットからフリーソフトをダウンロードしてくれば済むが、
昔、具体的に言うと'80年代は買うか、雑誌に載っていたら打ち込むか、自作するぐらいしかなかった。
私の場合は自作しか選択肢が無く、とりあえずBASICで作り始めた。
思い出すと恥ずかしいが、当初はバカ正直に IF A=&H00 THEN PRINT "NOP" の羅列で、あまりにも工夫がなかった。
まあ、でもとりあえず動けば良いという勢いは大事だ。難しい事はあとから考える。
そのうち命令コードの規則性に気づいて、少しずつ整理していった。
たとえば 01 XXX YYY はレジスタ同士のLD命令(一部は違う)
LD X,Y
XXX YYYの部分は下記の通り。
000:B
001:C
010:D
011:E
100:H
101:L
110:(HL)
111:A
但し、LD (HL),(HL)に相当する命令は無く、01 110 110 は 76h (HALT)
余談だが LD A,A などの命令は無駄じゃないかと思う。なんで存在するのだろう。規則上、できてしまっただけ。
こんなふうにBASICで逆アセンブラを作っていたが、マシン語のCB、DD、EDで始まる命令までは手が回らず、8080と互換性のある命令ぐらいまでで終わった。BASICだとあまりにもメモリが足りなかった。当時MZ-2000のHu-BASIC上で作っていたけど、フリーエリアが確か24Kぐらいしか無かった。
遅いのは全然構わなかった。ほっといて忘れた頃に出来上がっていればよいのだから。
あと、ラベルを付ける機能まではできなかったな。ラベルを付けると見やすいけれど、それなりの処理が必要だし、そのためのワークエリアも。
バイナリレベルだと命令なのかデータなのか、逆アセンブラで判断させるのは難しい。人間だったらダンプを見て、文字に変換されているところをみれば、ああ、このへんはメッセージが入ってるとか、BASICの中間言語のテーブルだろう、キャラクタの形状だろうって推測できるけれど。
たとえばROMの内容を読み出して、ソースを再現したり解析したりする時に使う。
今ではネットからフリーソフトをダウンロードしてくれば済むが、
昔、具体的に言うと'80年代は買うか、雑誌に載っていたら打ち込むか、自作するぐらいしかなかった。
私の場合は自作しか選択肢が無く、とりあえずBASICで作り始めた。
思い出すと恥ずかしいが、当初はバカ正直に IF A=&H00 THEN PRINT "NOP" の羅列で、あまりにも工夫がなかった。
まあ、でもとりあえず動けば良いという勢いは大事だ。難しい事はあとから考える。
そのうち命令コードの規則性に気づいて、少しずつ整理していった。
たとえば 01 XXX YYY はレジスタ同士のLD命令(一部は違う)
LD X,Y
XXX YYYの部分は下記の通り。
000:B
001:C
010:D
011:E
100:H
101:L
110:(HL)
111:A
但し、LD (HL),(HL)に相当する命令は無く、01 110 110 は 76h (HALT)
余談だが LD A,A などの命令は無駄じゃないかと思う。なんで存在するのだろう。規則上、できてしまっただけ。
こんなふうにBASICで逆アセンブラを作っていたが、マシン語のCB、DD、EDで始まる命令までは手が回らず、8080と互換性のある命令ぐらいまでで終わった。BASICだとあまりにもメモリが足りなかった。当時MZ-2000のHu-BASIC上で作っていたけど、フリーエリアが確か24Kぐらいしか無かった。
遅いのは全然構わなかった。ほっといて忘れた頃に出来上がっていればよいのだから。
あと、ラベルを付ける機能まではできなかったな。ラベルを付けると見やすいけれど、それなりの処理が必要だし、そのためのワークエリアも。
バイナリレベルだと命令なのかデータなのか、逆アセンブラで判断させるのは難しい。人間だったらダンプを見て、文字に変換されているところをみれば、ああ、このへんはメッセージが入ってるとか、BASICの中間言語のテーブルだろう、キャラクタの形状だろうって推測できるけれど。
昔と今のモデム
2024.11.27
昔はボックス型、そして内蔵ボード型、現在はUSB型
昔と今を比較すると非常に小さくなった。
ボックス型の中身(Deskporte V.34ESII)

USB型の中身

昔はモデム信号処理を専用LSIで行っていた。それとPC本体とのやりとりや制御のためのコントロールLSIとROM、RAMを組み合わせていた。
さらに回線周りのアナログ回路(DAAと呼ばれる)があった。
今では小さなIC、LSIが3個! USBメモリよりは大きいが、それでも十分小さいサイズにおさまっている。
信号処理をPC側のソフトで行うようになったので、その分、小型化できたというわけです。
ただ、この私が持っている個体はノイズに弱いような気がする。疑似交換機を通して別のモデムと接続してみたが、21,600bpsしか出なかった。
パソコンからUSB経由で電源をもらっているから、当然ノイズがのっている。パソコンにイヤホンをさして、無音状態の時でもチリチリジリジリとノイズが聞こえてくるぐらいだから・・・。
この点では、ボックス型のほうが有利といえそう。もちろんトランス式のACアダプタを使っている機種。
昔と今を比較すると非常に小さくなった。
ボックス型の中身(Deskporte V.34ESII)

USB型の中身

昔はモデム信号処理を専用LSIで行っていた。それとPC本体とのやりとりや制御のためのコントロールLSIとROM、RAMを組み合わせていた。
さらに回線周りのアナログ回路(DAAと呼ばれる)があった。
今では小さなIC、LSIが3個! USBメモリよりは大きいが、それでも十分小さいサイズにおさまっている。
信号処理をPC側のソフトで行うようになったので、その分、小型化できたというわけです。
ただ、この私が持っている個体はノイズに弱いような気がする。疑似交換機を通して別のモデムと接続してみたが、21,600bpsしか出なかった。
パソコンからUSB経由で電源をもらっているから、当然ノイズがのっている。パソコンにイヤホンをさして、無音状態の時でもチリチリジリジリとノイズが聞こえてくるぐらいだから・・・。
この点では、ボックス型のほうが有利といえそう。もちろんトランス式のACアダプタを使っている機種。