なんとかなるさね

マイコンをネタにブログを始めてみました


RL78マイコン|プログラムが変なところでブレークする様子をシミュレータで見てみた 

以前のエントリで上位16bitリードと下位16bitリードの隙間で割り込みが発生して割り込み処理でリード途中の
32bit全体のインクリメントが行われてしまうトレースデータを作ってみたのですが、今度はプログラムが変な
ところでブレークしてしまうトレースデータを作ってみました。試したプログラムは以下の通りです。

void main(void)
{
    R_MAIN_UserInit();
    /* Start user code. Do not edit comment generated here */
    NOP();
    /* End user code. Do not edit comment generated here */
}

void R_MAIN_UserInit(void)
{
    /* Start user code. Do not edit comment generated here */
    int var[2];
    int i;
    
    for ( i = 0; i < 5; i++ )
    {
        var[i] = 0x5555;
    }
    return;
    /* End user code. Do not edit comment generated here */
}




このプログラムを実行すると以下のように変なところでシミュレーションが停止します。



トレースデータは以下の通りです。プログラムでスタック上のリターンアドレスのデータ(0xffed8~0xffedb)を
破壊してしまっていますので、RET命令を実行したとたんにプログラムが変なところへ飛んで行きます。



なお、スタック上のリターンアドレスのデータ(0xffed8~0xffedb)を破壊している様子は以下の通りです。




もう1つプログラムを試してみました。試したプログラムは以下の通りです。

void main(void)
{
    R_MAIN_UserInit();
    /* Start user code. Do not edit comment generated here */
    for (;;)
    {
        void (*fnp)(void);
        int var[2];
        int i;
        
        *fnp = R_MAIN_UserInit;
        for ( i = 0; i < 4; i++ )
        {
            var[i] = 0x5555;
        }
        (*fnp)();
        NOP();
    }
    /* End user code. Do not edit comment generated here */
}

void R_MAIN_UserInit(void)
{
    /* Start user code. Do not edit comment generated here */
    return;
    /* End user code. Do not edit comment generated here */
}




このプログラムも実行すると以下のように変なところでシミュレーションが停止します。



トレースデータは以下の通りです。プログラムでスタック上の関数ポインタのデータ(0xffed6~0xffed8)を破壊
してしまっていますので、関数呼び出しを実行したとたんにプログラムが変なところへ飛んで行きます。



なお、スタック上の関数ポインタのデータ(0xffed6~0xffed8)を破壊している様子は以下の通りです。




ちなみに、内蔵ROMサイズが64Kバイト以上の場合の関数ポインタはfarポインタですが、farポインタ変数の
アクセスはアトミックじゃないです。ですので、割り込み処理でfarポインタを書き換えて通常処理で読み出し
たり逆に通常処理でfarポインタを書き換えて割り込み処理で読み出したりするプログラムでは、アクセスの
衝突を防止するようにしないと危ないです。

関連記事

2015/02/01   blog-entry-563   category: RL78 /* 16bit,8bit CISC */

go page top