GNU asで、Z8001のアセンブリコードを書く際の注意点を書き留めておきます。
アドレスを直打ちする場合は、アドレスのbit31を1にする必要があります。そうしないと、アドレスの上位2byteが短縮アドレスとして扱われてしまいます。アドレスをラベルで指定する場合は、この問題はありません。
セグメントアドレス
アドレスを直打ちする場合は、アドレスのbit31を1にする必要があります。そうしないと、アドレスの上位2byteが短縮アドレスとして扱われてしまいます。アドレスをラベルで指定する場合は、この問題はありません。
例えば
ld r0, 0x01000008
の場合、アセンブルされたコードは、
ld r0, 0x0100
addb rl0, #xx
のように、アドレスの上位2byte が短縮アドレスになり、下位2byteは別の命令になってしまいます。
バクなのか、そういう仕様なのかはわかりませんが、これで2日間ほどはまりました。
ちなみに、asでは、セグメントアドレスを <<セグメント番号>> で表記できません。
セグメントモードだと、アドレスが32bitになってしまい、アドレス指定に必ず 4byte 使われてしまいます。なので、変数はメモリ上に置かず、できるだけレジスタに置いた方が、アドレス指定に消費するメモリが少なくなります。レジスタはZ80に比べたら山のようにあるので問題はないでしょう。
変数をメモリ上に取るときは、間接アドレッシングを使った方がメモリ効率は良さそうです。ローカルな変数は、Cのようにスタック上に置いた方が良いのかもしれませんが、アセンブリ言語で管理するのは面倒な気もします。
Z8001の場合、R0〜R7は、上位下位に分けて8bitレジスタとして使えるので、間接アドレッシングを使うなら、RR8以降を使ったほうがよさそうです。RR14はスタックポインタとして使うので、RR8, RR10, RR12を使うことができます。Z80のIX,IY プラス 1レジスタと考えると、ちょっと得した気分になれます。
ld r0, 0x01000008
の場合、アセンブルされたコードは、
ld r0, 0x0100
addb rl0, #xx
のように、アドレスの上位2byte が短縮アドレスになり、下位2byteは別の命令になってしまいます。
バクなのか、そういう仕様なのかはわかりませんが、これで2日間ほどはまりました。
ちなみに、asでは、セグメントアドレスを <<セグメント番号>>
ダイレクトアドレッシング
セグメントモードだと、アドレスが32bitになってしまい、アドレス指定に必ず 4byte 使われてしまいます。なので、変数はメモリ上に置かず、できるだけレジスタに置いた方が、アドレス指定に消費するメモリが少なくなります。レジスタはZ80に比べたら山のようにあるので問題はないでしょう。
変数をメモリ上に取るときは、間接アドレッシングを使った方がメモリ効率は良さそうです。ローカルな変数は、Cのようにスタック上に置いた方が良いのかもしれませんが、アセンブリ言語で管理するのは面倒な気もします。
間接アドレッシング
Z8001の場合、R0〜R7は、上位下位に分けて8bitレジスタとして使えるので、間接アドレッシングを使うなら、RR8以降を使ったほうがよさそうです。RR14はスタックポインタとして使うので、RR8, RR10, RR12を使うことができます。Z80のIX,IY プラス 1レジスタと考えると、ちょっと得した気分になれます。
0 件のコメント:
コメントを投稿