例えば、1文字出力のプログラムを、いたる所で呼び出したいとする。
                    .
                    .
                mov.l #0,er0
                jmp putchar
            L0:     .
                    .
                mov.l #1,er0
                jmp putchar
            L1:     .
                    .
                mov.l #2,er0
                jmp putchar
            L2:     .
                    .
            putchar:
                .           なんかやってる
                .
                cmp.l #0,er0
                bz    L0
                cmp.l #1,er0
                bz    L1
                cmp.l #2,er0
                bz    L2

        以上のように、3つくらいならばいいが、100ヶ所から呼び出されると
        したら、困ってしまう。
                    .
                    .
                mov.l #L0,er0
                mov.l er0,@NextJump (NextJumpはRAMの領域)
                jmp   putchar
            L0:     .
                    .
                mov.l #L1,er0
                mov.l er0,@NextJump
                jmp   putchar
            L1:     .
                    .
                mov.l #L2,er0
                mov.l er0,@NextJump
                jmp   putchar
            L2:     .
                    .
            putchar:
                .           なんかやってる
                .
                mov.l @NextJump,er0
                jmp   er0
        この方法も、サブルーチン毎に変数を用意してやらないと
        いけないので大変である。

        以上のような、プログラムの呼出は、頻繁に使われるため、
        以下のように名前が付いている。
            あるプログラムのまとまりを呼び出す操作->サブルーチンコール
            呼び出される側->サブルーチン
        これも非常に面倒くさい。

        で、スタックというのを用意する。

                    .
                    .
                jsr putchar :L0のアドレスをスタックに積んで jump
            L0:     .
                    .
                jsr putchar :L1のアドレスをスタックに積んで jump
            L1:     .
                    .
                jsr putchar :L2のアドレスをスタックに積んで jump
            L2:     .
                    .
            putchar:
                .           なんかやってる
                .
                rts         :スタック上のアドレスをプログラムカウンタに入れる
        この機構は、サブルーチンの中でサブルーチンを呼び出している場合にも
        有効である(付録:スタック)。
        このCPUの場合には、er7 をスタックとして利用している。

        h8300-hms-gcc -mh 1.s -o 1.x
        h8300-hms-gdb 1.x
            TargetSettings で、Targetを Simulator を選択
            一度RUNを押す

    (8)待避領域としてのスタック
        あるサブルーチンが、r0〜r3 を破壊してしまうとする。
        呼出側のプログラムでは、r0〜r3 までを破壊されたくない場合には、
            push    r0
            push    r1
            push    r2
            push    r3
            jsr     サブルーチン
            pop     r3
            pop     r2
            pop     r1
            pop     r0
        などとする
    (9)一時的変数領域としてのスタック
        C言語では、関数内の auto 変数は、全てスタックに取られる。

インターネット上の、スタックを分かり やすく説明しているページ


マイコンプログラム実習へ戻る