2018.6.23
前へ
次へ
ホームページトップへ戻る


16ビットマイコンボードの製作

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第41回]



●8086のメモリアドレッシング

ずっと長年Z80に慣れ親しんできましたので、このところのように8086のアセンブラプログラムを書いていても、ついZ80の頭で考えてしまいます。
今回のテーマのメモリアドレッシングについてもZ80と8086では基本的なところで相違があります。
8086のメモリアドレッシングについて、よく確認しないで、Z80と同じだろうぐらいの気持ちでプログラムを書いてしまい、エラーメッセージの洪水に見舞われてしまったりします。
先日もいい加減なメモリアドレッシングの命令を書いてアセンブラに拒否されてしまいました。
それでこの機会に、8086のメモリアドレッシングについてきちんと整理しておくことにしました。

メモリアドレッシングというとなんだか難しいようですが、突き詰めて言えば、あるメモリの中身を参照したり書き換えたりするときに、そのメモリアドレスを指定する方法のことです。
最も基本的なアドレッシングはダイレクトアドレッシング(直接アドレス指定)で、たとえばZ80の命令表記で
LD ($1234),HL
などのようにアドレスを直接指定する方法です。
直接アドレス指定に対して、レジスタに入っている値を使ってメモリアドレスを指定する間接アドレス指定があります。
LD A,(HL)
などのように2バイトのレジスタを使ってメモリを指定します。
Z80では定番のHLのほかに、IX、IYをこの用途に使うことができます。
LD先、LD元レジスタがAレジスタの場合に限ってBC、DEを使うことができます。
そのほかにEX(エクスチェンジ)命令に限って、SPも使うことができます。
EX (SP),HL
EX (SP),IX
EX (SP),IY
これらはスタックトップとHL、IX、IYの値を交換する命令です。
今回うっかりして8086でこのタイプの命令を使おうとしてエラーで引っかかってしまいました。



前回のところからがんばって、ここまでエラーが減りました。
その中で
[00581]のXCHG SI,[SP]
がエラーになっているのに気が付きました。
ここはZ80のプログラムでは
EX (SP),HL
としていたところです。
EX (SP),HL
の代わりの命令が無い???
いや、それは困る…。

念のためにそのところだけを抜き出したテストプログラムを書いて8086アセンブラにかけてみましたがやはりエラーになってしまいました。

いや。
この命令は使いたいときがあるでしょうよ。
むむ。
ひょっとすると、わが自作8086アセンブラに落ちがあるのかも。
そこで、あらためて8086のメモリアドレッシングについて確認してみることにしました。

こちらはインテルの80C186、80C188のUser’s Manualです。

現在作業中のキットに使うのはAMDのAM188ですが、80C188互換なので今回はこのマニュアルで確認します。

命令のバイナリコードの組み立てについて説明しているところですが、このページにメモリアドレッシングについてのまとめがあります。

左側のr/mのところですが、ここを見ると、メモリアドレスに利用できるレジスタはBX、BP、SI、DIのみのようです。
そういうことだったのでした。
8086はレジスタの用途に幅をもたせて、汎用の用途にはセグメントレジスタ以外のレジスタはかなり自由に使うことができます。
比較のためにまずZ80の場合について書きます。
Z80ではADD、SUB、AND、OR、XOR命令などの第一オペランドには8ビットではAレジスタしか使えません。
16ビットはADD、SBCの第一オペランドにはHL、IX、IYのみが使えますがBC、DEは使えません。
また16ビットの論理演算命令(AND、ORなど)はありません。

その点8086はほとんど制約なく使えます。
ADD BX,CXもSUB DX,AXもOKです。
OR SI,DIなどという使い方もできます。
ところが今回確認したメモリアドレッシングについては、上に書きましたようにBX、BP、SI、DIのみ使うことができて、そのほかのレジスタAX、CX、DXはその用途には使えません。
SPも使えないことがわかりました。
8086のレジスタについては汎用と専用について区別して定義されているようです。
汎用の演算などの用途にはほとんど全てのレジスタを自由に使うことができます。
しかし専用の用途(今回の間接メモリアドレッシングもそのひとつです)についてはかなり限定されています。
たとえばIN、OUT命令のアドレス指定にはDXしか使えません。
また同じくIN、OUT命令のデータレジスタにはAXかALしか使えません。
繰り返し命令のカウンタにはCXしか使えません。

ということで、本題のXCHGに戻ります。
こちらにXCHGのバイナリコードについての表があります。

ちょっと小さいですけれど下から10行ほど上に行ったところにXCHGがあります。
そこのregister/memory with registerが今回問題になったところです。
右の2バイト目のところには mod reg r/m とあって、メモリアドレッシングとしては、先ほどの表のr/mがあてはまることがわかります。
つまりはXCHG [SP],SIはだめ、ということです。
r/mに[SP]はありませんから、XCHGに限らず、MOV [SP],AXなどのような使い方もできないということになります。

XCHG [SP],SIが使えないということになると、それじゃあZ80のEX (SP),HL(8080ではXTHL)については8086ではどのようにすればよいのか?
ということなのですが、聡明なる読者諸賢におかれましては、もうおわかりかと思います。
昨日も本日も一日ぶっ通しで8086版BASICの倍精度浮動小数点演算プログラムに没頭しておりまして、時間がありません。
その答えにつきましては次回に書くことにいたします。

ところで。
本日までの成果です。
やっとここまで動くようになりました。


DOS窓で実行しているのが作成中の8086版BASICです。
よく見ると√2と√3の末尾3桁ほどが違っています。
そのほかは末尾まで一致しています。
全く同じプログラムが動いているのですがねえ。
こういうのが一番難しいのです。
これをどうやって解決するか。
また明日一日中悩むことになりそうです。

16ビットマイコンボードの製作[第41回]
2018.6.23upload

前へ
次へ
ホームページトップへ戻る