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

  • > 逆アセンブルの③のところで、BR AX (AXレジスタで示すアドレスにジャンプ)
    > するはずが、AXの値が0のままになってしまっています。よって、0番地にジャンプ

    見た感じ、

    > 790020 MOVW AX,2000H[BC]

    AXにミラー領域を通してジャンプ先の下位16ビットを取得して

    > 61cb BR AX    ;<<<<<<<<<<<<<<<<<③

    ジャンプしてるようなので、AXが0になるのだとしたらミラー領域が間違ってる可能性が高いと思います。マイコンの種類の設定を間違えてミラー領域が正しくない番地になってるのでは。

    あと直接関係ないとは思いますが

    > unsigned char v,x;
    > v=1;     //①
    > switch(v){
    > case 0:x=x+1;break;

    変数 x の値が未初期化操作してしまっており、未定義動作を踏んでいます。
  • コメントありがとうございます。
    >AXが0になるのだとしたらミラー領域が間違ってる可能性が高いと思います。
    確かにそうなのかと思うのですが、
    以下の④のところにアセンブラ命令レベルでブレーク設定して、ステップ実行
    すると、AXには、ジャンプ先アドレスが転送され、③のジャンプが成功するの
    で混乱しています。④のブレーク設定せず実行する場合NG、E2Liteなしの、
    HEX書き込みでもNGでした。

    x未定義ご指摘の通りです。


    790020 MOVW AX,2000H[BC] <④
    61cb BR AX    ;<<<<<<<<<<<<<<<<<③
  • マイコンの種類の設定は確認されましたか?
  • > AXの値が0のままになってしまっています。よって、0番地にジャンプするので、リセット時同様の挙動になってしまう。

    RL78 の 0番地はリセットベクタでありプログラムの開始番地ではないので、仮にそこへ分岐したとしてもリセット時同様の挙動になるとは限りません。不正命令やパリティエラーかなんかでソフトウェアリセットが掛かっているのを 0番地に分岐したと誤解されてはいませんか?
  • nyanさん、こんにちは。NoMaYと申します。

    以下の③でAXがゼロになるのであれば、その前の命令の実行の時、BCレジスタ値と(BC+0x2000)番地のメモリ値がどうなっているか知りたいです。CS+(だと思われますが)の画面コピーを見せて頂けませんか?

    > 790020 MOVW AX,2000H[BC]
    > 61cb BR AX    ;<<<<<<<<<<<<<<<<<③

  • ご指摘のマイコン型番ですが、改めて確認したところ、現物は、ROM96K品、CS+の設定は64Kでした。
    これが、原因かもしれません。64Kの現物入手して確認してみます。
    >RL78 の 0番地はリセットベクタであり・・・・・・
    アセンブラレベルで0番地にジャンプする前の以下の④でブレークして確認していますので、
    多分その線は無いかと思います。
    また、CS+デバッガでCPUリセット直後に、PC値を main1のアドレスに設定しても同じ挙動を
    示しますので、割り込み関連のベクタ設定ミスでは無いと判断しました。

    790020 MOVW AX,2000H[BC] <④
  • > ご指摘のマイコン型番ですが、改めて確認したところ、現物は、ROM96K品、CS+の設定は64Kでした。

    > これが、原因かもしれません。

    RL78/G13 の ROM96kB の製品はミラー領域の開始がF3000H、64kB の製品はF2000Hなのでそれが原因でしょう。

    > 64Kの現物入手して確認してみます。

    フツーは CS+ の設定を修正変更するところだと思います。

  • > >RL78 の 0番地はリセットベクタであり・・・・・・
    > アセンブラレベルで0番地にジャンプする前の以下の④でブレークして確認していますので、
    > 多分その線は無いかと思います。

    ハードウェアマニュアル見れ
  • nyanさん、こんにちは。NoMaYです。

    追加ですが、同じ時のシミュレータでの画面コピーも見たいです。

    > 以下の③でAXがゼロになるのであれば、その前の命令の実行の時、BCレジスタ値と(BC+0x2000)番地のメモリ値がどうなっているか知りたいです。CS+(だと思われますが)の画面コピーを見せて頂けませんか?
    > > 790020 MOVW AX,2000H[BC]
    > > 61cb BR AX    ;<<<<<<<<<<<<<<<<<③

  • お騒がせしました。96K品のミラー領域3000H~というのを軽視していました。
    CS+側設定96K設定にしたところ、AX,3000H [BC]にコード生成され、問題なく
    実行できるようになりました。

    cefc00 MOV CS,#0H
    790030 MOVW AX,3000H[BC]  <<<<<<
    61cb BR AX

    fujita nozomu 様ありがとうございました。