switch 文使用時の挙動 (最適化なし時)

お世話になります。

以下プログラムで、

ビルドツールの設定を最適化なし

E2Liteを使いRL78/G13の実チップにてデバッグ(自動生成ツールの設定=デバッグあり)

ブレーク設定を①、②に設定

 にて試しているのですが、

①で、停止後、F5で実行をすると、②で停止する予定が停止せず、

また①に戻ってしまいます(リセットしてしまう)

  ※シミュレータでは、ちゃんと②で停止します。

 

void main1(void)  //自動生成コードmain からの飛び先

{
unsigned char v,x;
    v=1;     //①
    switch(v){
        case 0:x=x+1;break;
        case 1:x=x+1;break;
        case 2:x=x+1;break;
        case 3:x=x+1;break;
        case 4:x=x+1;break;
    }
    while(1){
        x=x+1;     //②
    }
 }

調べると、switch 文は、最適化なしでは、テーブルジャンプコードに

生成されるようで、以下 逆アセンブルの③のところで、BR AX  (AXレジスタで示すアドレスにジャンプ)

するはずが、AXの値が0のままになってしまっています。よって、0番地にジャンプするので、リセット時

同様の挙動になってしまう。この理由がわからず困っています。宜しくお願い致します。

void main1(void)

{

_main1:
c7 PUSH HL
c1 PUSH AX
fbf8ff MOVW HL,SP

unsigned char v,x;

v=1;

cc0101 MOV [HL+1H],#1H
switch(v){

e1 ONEB A
318e SHRW AX,8H
440500 CMPW AX,#5H
de24 BNC $_main1+0x34
12 MOVW BC,AX
490a20 MOV A,200AH[BC]
311c SHLW BC,1H
9efc MOV CS,A
790020 MOVW AX,2000H[BC]
61cb BR AX    ;<<<<<<<<<<<<<<<<<③

 

case 0:x=x+1;break;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
ef12 BR $_main1+0x34
case 1:x=x+1;break;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
ef0d BR $_main1+0x34
case 2:x=x+1;break;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
ef08 BR $_main1+0x34
case 3:x=x+1;break;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
ef03 BR $_main1+0x34
case 4:x=x+1;break;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
}

 

while(1){

 

x=x+1;

8b MOV A,[HL]
81 INC A
9b MOV [HL],A
}

effb BR $_main1+0x34

 

}

c0 POP AX
c6 POP HL
d7 RET

Parents
  • nyanさん、こんにちは。NoMaYです。

    こういうことだったのかな、と思いました、、、

    (A) コンパイラ設定:ROM=64K(MIRROR=F2000H~) & シミュレータ設定:ROM=64K(MIRROR=F2000H~)
    動作して当然である筈であり、実際、nyanさんの手元で動作した

    (B) コンパイラ設定:ROM=64K(MIRROR=F2000H~) & ハードウェアデバッガ設定:ROM=64K(MIRROR=F2000H~)

    (B-1) もしもデバッグに使用した実デバイス:ROM=64K(MIRROR=F2000H~)だったなら
    動作して当然である筈であり、きっと、nyanさんが該当実デバイスを入手して試したら動作すると思われる

    (B-2) しかしデバッグに使用した実デバイス:ROM=96K(MIRROR=F3000H~)だった
    動作しなくて当然といえば当然であり、実際、nyanさんの手元で動作しなかった

    nyanさんの投稿から推測すると

    此の実デバイスでF2000H~F2FFFHをリードするとゼロがリードされる
    (というか此の実デバイスではF2000H~F2FFFHはデータフラッシュメモリ(リセット解除後は停止状態)の領域ですね)

    よって

    790020 MOVW AX,2000H[BC] → BC+2000H=2002HならF2002H番地が読み出されてAX=0となる
    61cb   BR AX → AX=0となったのだから0番地へジャンプする

    以後推測です(fujita nozomu氏が言いたかったことなのかもと思います)

    0番地はリセットベクタが書かれているのだが、0番地からを命令コードとして実行

    どんどんと実行していくうちに安全機能設定によりリセットを発生させるような命令を実行
    (というか安全機能設定が全OFFでも命令コード0xFFを実行すると実デバイスでは(デバッグ時以外は)リセットが発生します)

    リセットが発生

    リセットルーチンの先頭から実行

    main1()の先頭の①に戻る

     

  • NoMaY さん
    解説ありがとうございます。
    その通りだと思います。
Reply Children
No Data