うさちゃんと一緒(24) Z80の魔改造?Rabbit4000でアセンブラその2

Joseph Halfmoon

前回Rabbit4000のアセンブラをちょいと触ってみました。インラインでもインラインでなくてもCのソースと混然一体。Cからアセンブラへの敷居がとても低かったです。今回はインラインアセンブラのコードの中にCのステートメントを書ける「インラインC?」に始まって独特なところをまた触ってみたいと思います。

※Rabbitシリーズのマニュアルは、販売元のDigi社のページからダウンロードできます。

インラインアセンブラ部分の中にCのステートメントが書ける

前回、Dynamic Cの場合、Cのソースのどこでも「#asm」と書けばアセンブラを書き始められることがわかりました。Cの関数内で#asmとすれば「インラインアセンブラ」となり、関数の外側で#asmすれば独立のアセンブラ・ルーチンを書くことができました。

今回ちょいと普通じゃないと思うのは、#asmとして書き始めたインラインアセンブラ部分の中で、Cのステートメントをかけてしまう、という件。インラインアセンブラコードの中のインラインCコード?です。さすがにアセンブラとCの識別が必要なので、

行頭にCと書く

とCのステートメントと理解してコンパイルしてくれるようです。「行頭にCと書く」なぜか懐かしく感じるのは大昔、FORTRANをならっていたからですな。FORTRAN(今ではFortranと書くべきか)は最強。

実際にインラインアセンブラコードの中でCのステートメントを「ことさら」利用している例が以下に。

ASM2_inlineC

インラインアセンブラでfarポインタを使ってみる

16ビットアドレスのZ80に比べ、物理アドレス空間最大24ビットにアクセスできるRabbit4000は、その広い空間に直接アクセスできるfarポインタをもってます。このあたりはi8086などと似てます。勿論、Cでもアセンブラでもfarポインタで示されるアドレスはハンドリング可能です。こんな感じ。

ASM2_farPtr

 

farポインタを使うと、Z80の枠からはみ出ちゃった感?が強いです。ボイジャー的な?

#asm debug キーワード

上のコード例でつい「#asm debug」書いてしまいました。本来の「#asm」とだけ書く書き方で上のコードを書くならば以下のようなコードが生成されます。ASM2_disassemblerNODEBUG

ところが、debug と一言追加すると以下のようなコードが生成されます。ASM2_disassembler

RST 0x28命令(1バイトのソフトウエア割り込み命令)が命令の間にちりばめられてます。

どうもDynamic Cは、ソフトウエア・ブレークポイント、シングル・ステップ等にRST 0x28命令を多用しているみたいです。書き込み先がFlashでもRAMでも、オブジェクトコードの生成時にRST 0x28命令をちりばめておいてデバッグに対応してます(当然、オフにしてRSTを生成しないこともできる。リリース時にはこちらね。)

よりモダンなハードウエアレジスタでブレークをかけられる機能があるようですが、ソフトウエア方式のほうが使いやすいUIのような気がします。知らんけど。

今回実験のC言語(インラインアセンブラ含む)ソース

関数 addB() などは、せっかくCでいろいろやっているのに、インラインアセンブラでそれを全否定して値を上書きするという暴挙にでてます。これは「行頭にCと書く」を実践するためであります。addC()関数にはmain()関数から呼び出すときにfar 変数のアドレスを渡しています。far宣言気にしなければ普通にできますな。

#class auto

int addB(int arg1, int arg2) {
    int		tmp = 333;
    int		wrk;
    if (arg1 > tmp) {
        wrk = arg1;
    } else if (arg1 > arg2) {
        wrk = arg2;
    }
#asm
c	wrk = 999;
    ld		hl, (sp+@sp+wrk)
#endasm
}

far int fii;

int addC(far int *ptr) {
#asm debug
    ld px, (sp+@sp+ptr);
    ld de, (px);
    ld hl, 1;
    add hl, de;
    ld (px), hl
#endasm
}

void main()
{
    int src, src2, dst;

    printf("Rabbit4000 ASM Training 2.\n");
    src = 55;
    src2 = 11;
    dst = addB(src, src2);
    printf("addB: %d %d -> %d\n", src, src2, dst);

    fii = 621;
    addC(&fii);
    printf("addC: %d\n", fii);
}
実行結果

実行結果は以下の通りです。

ASM2_Results

だんだん、うさちゃんの深みにはまっている気がしないでもないデス。

うさちゃんと一緒(23) Z80の魔改造?Rabbit4000でアセンブラしてみる へ戻る

うさちゃんと一緒(25) Z80の魔改造?Rabbit4000でDNSクエリその1 へ進む