スタックポインタとローカル変数

平成20年7月26日

    スタックは内部高速RAM(0FB00Hから0FEFFH)に配置されます。

    C言語で書いたローカル変数(関数の中で宣言した変数)はスタックに格納されますが、内部高速RAMは1kバイトしかないので、あまりたくさんの領域をとることができません。

    トラ技BIOSが起動して、ユーザアプリケーションが動き出したときには、いったいどこを指しているのでしょうか。スタックに余りがいっぱいあれば、大きな配列(とはいっても500バイトくらいですが、このクラスのマイコンにとっては十分な大きさです)を動的に確保することができます。

     

スタックポインタの初期値

    スタックポインタの値を調べるには、アセンブラの命令を使う必要があります。

    MOVW    AX,SP

    という命令を実行すると、SPの値がAXに格納されます。

    ただ、この後、AXをC言語の変数に入れる方法がわからない※1ので、メモリ上にAXレジスタの値を格納することにします。

    ※関数呼び出し時の第一引数がAXに入るので、C言語の関数をCALL命令で呼んでやればよい気もする。

     

    次のコードは、SPの値をF708番地に格納するコードです。アセンブラソースとして作成し、プロジェクトに追加します。

    このコードはC言語のプログラムからcheck_sp()関数で呼び出せます。

    PUBLIC  _check_sp
    @@CODE CSEG

    _check_sp:
            PUSH    HL
            MOVW    HL,#0F708H
            MOVW    AX,SP
            MOV             [HL],A
            INCW    HL
            MOV             A,X
            MOV             [HL],A
            POP     HL
            RET
    END
     

     

    実行前

    >dump f700 10
    F700 08 58 28 2F 18 FF 50 F5 F2 77 54 54 14 CD 0F 2E .X(/..P..wTT....
     

    実行後

    >jmp f000
     
    ユーザプログラムを実行します
    スタックポインタを調べます
     
    実行完了
    >dump f700 10
    F700 08 58 28 2F 18 FF 50 F5 FE 10 54 54 14 CD 0F 2E .X(/..P...TT....
     

    スタックポインタはFE10を指しているようです。

    しかし、動的に256バイトの配列を取ったらプログラムがうまく動作しませんでした。まだまだ謎が潜んでいるのかもしれません。

    check_sp関数のプロジェクトを check_sp.lzh に置いておきます。ご自由にお使いください。

 

 

chickens_back.gif 戻る

 Copyright(C) 2008 NAITOU Ryuji. All rights reserved. 無断転載を禁ず