RL78のローカル変数のメモリアドレスについて

こんにちは。SUZUKIです。

 

RL78/G14用のプログラムをCS+で開発中に良く分からない現象に遭遇しました。

プログラムは

void test(char a){

char b = 0;

b = a+10;

}

という簡単なものです。

この時に変数a,bをウォッチするとアドレスがそれぞれ[L:REG][H:REG]となっており、変数bの値は0のままでした。

動作する条件としては下記3つありました。

1.変数bの宣言をグローバルで行った場合

2.別の変数(使用しない)を関数内で宣言した場合

3.変数bの型をint型にした場合

これらの時は変数a,b共にアドレスが割り当てられ正常に動作しました。

これはどのような事が起きているのでしょうか。

宜しくお願い致します。

Parents
  • SUZUKIさん、こんにちは。NoMaYです。すみません。夜遅くなるどころか日付まで変わってしまいました。

    CA78K0RとCC-RLでコンパイラが生成するコードを調べてみました。試したプロジェクトは以下のzipファイルに固めてあります。ただ、書いてみて思ったのですが、もっと分かり易く書き直さないと駄目な気がします。もう少し、書き方を考えてみようと思います。

    Issue_20171214.zip

    具体的には以下のソースコードに対して2×3=6つの条件でコンパイルして、コンパイルリストを出力させ、変数bへの代入がどうなっているかアセンブラコードを調べました。

    void test(char a){
        /* volatile */ char b = 0;
        b = a+10;
        R_DAC0_Set_ConversionValue(b);
    }

    (1) CA78K0R V1.72
    (2) CC-RL V1.02 (当方特有の事情で最新版では無いです)

    (A) 最適化なし
    (B) プロジェクト作成時のデフォルトの最適化
    (C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言

    今回の件は(1-B)に該当するのですが、わわいさんがアドバイスしている通り、最適化のため変数への値の代入がなされなかった、ということです。ただ、ちょっと紛らわしいことに、もう少しCA78K0Rが賢ければ多分なされなかったと思われる「0を代入する」ことは行われており、それに対して「a+10を代入する」ことだけが行われなくなっていたので、ということでした。(ちなみに、CC-RLでは「0を代入する」ことも行われなくなっていました。)

    (1) CS+ for CA,CX V4.00.01 + CA78K0R V1.72




    (1-A) 最適化なし ⇒ 0(00H)や変数a+10(0AH)を変数bへ代入している

      760   760                      ; line    83 : void test(char a){
      761   761 00012                _test:
      763   763 00012  C7                    push    hl                                              ;[INF] 1, 1
      764   764 00013  C1                    push    ax (補)引数aをスタックに移す                    ;[INF] 1, 1
      765   765 00014  C1                    push    ax (補)変数bの領域をスタック上に確保する        ;[INF] 1, 1
      766   766 00015  FBF8FF                movw    hl,sp                                           ;[INF] 3, 1
      768   768                      ; line    84 :     /* volatile */ char b = 0;
      770   770 00018  CC0100                mov     [hl+1],#00H     ; b,0                           ;[INF] 3, 1
      771   771                      ; line    85 :     b = a+10;
      773   773 0001B  8C02                  mov     a,[hl+2]        ; a                             ;[INF] 2, 1
      774   774 0001D  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      775   775 0001F  9C01                  mov     [hl+1],a        ; b                             ;[INF] 2, 1
      776   776                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      778   778 00021  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す   ;[INF] 2, 1
      779   779 00023 RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      780   780                      ; line    87 : }
      783   783 00027  1004                  addw    sp,#04H                                         ;[INF] 2, 1
      784   784 00029  C6                    pop     hl                                              ;[INF] 1, 1
      785   785 0002A  D7                    ret                                                     ;[INF] 1, 6

    (1-B) プロジェクト作成時のデフォルトの最適化 ⇒ 0(00H)を変数bへ代入しているが、変数a+10(0AH)を変数bへ代入していない

      759   759                      ; line    83 : void test(char a){
      760   760 00012                _test:
      762   762 00012  C7                    push    hl                                              ;[INF] 1, 1
      763   763 00013  16                    movw    hl,ax                                           ;[INF] 1, 1
      765   765                      ; line    84 :     /* volatile */ char b = 0;
      767   767 00014  5700                  mov     h,#00H  ; 0                                     ;[INF] 2, 1
      768   768                      ; line    85 :     b = a+10;
      770   770 00016  66                    mov     a,l                                             ;[INF] 1, 1
      771   771 00017  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      772   772                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      774   774 00019  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す     ;[INF] 2, 1
      775   775 0001B RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      776   776                      ; line    87 : }
      779   779 0001F  C6                    pop     hl                                              ;[INF] 1, 1
      780   780 00020  D7                    ret                                                     ;[INF] 1, 6

    (1-C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言 ⇒ 0(00H)や変数a+10(0AH)を変数bへ代入している

      759   759                      ; line    83 : void test(char a){
      760   760 00012                _test:
      762   762 00012  C7                    push    hl                                              ;[INF] 1, 1
      763   763 00013  C1                    push    ax (補)引数aをスタックに移す                   ;[INF] 1, 1
      764   764 00014  C1                    push    ax (補)変数bの領域をスタック上に確保する        ;[INF] 1, 1
      765   765 00015  FBF8FF                movw    hl,sp                                           ;[INF] 3, 1
      767   767                      ; line    84 :     volatile char b = 0;
      769   769 00018  CC0100                mov     [hl+1],#00H     ; b,0                           ;[INF] 3, 1
      770   770                      ; line    85 :     b = a+10;
      772   772 0001B  8C02                  mov     a,[hl+2]        ; a                             ;[INF] 2, 1
      773   773 0001D  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      774   774 0001F  9C01                  mov     [hl+1],a        ; b                             ;[INF] 2, 1
      775   775                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      777   777 00021  8C01                  mov     a,[hl+1]        ; b                             ;[INF] 2, 1
      778   778 00023  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す     ;[INF] 2, 1
      779   779 00025 RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      780   780                      ; line    87 : }
      783   783 00029  1004                  addw    sp,#04H                                         ;[INF] 2, 1
      784   784 0002B  C6                    pop     hl                                              ;[INF] 1, 1
      785   785 0002C  D7                    ret                                                     ;[INF] 1, 6

    (2) CS+ for CC V6.00.00 + CC-RL V1.02




    (2-A) 最適化なし ⇒ 0(0x00)や変数a+10(0x0000A)を変数bへ代入している

    00000009                      121  _test:
    00000009                      122       .STACK _test = 6
    00000009                      127       ;***       84 : void test(char a){
    00000009 C7                   129       push hl (補)引数aと変数bの領域をスタック上に確保する
    0000000A 9801                 130       mov [sp+0x01], a (補)引数aをスタックに移す
    0000000C                      131       ;***       85 :    /* volatile */ char b = 0;
    0000000C C80000               133       mov [sp+0x00], #0x00
    0000000F                      135       ;***       86 :     b = a+10;
    0000000F 8801                 137       mov a, [sp+0x01]
    00000011 318E                 138       shrw ax, 8+0x00000 (補)AレジスタをAXレジスタ(作業用)に移す
    00000013 040A00               139       addw ax, #0x000A
    00000016 60                   140       mov a, x
    00000017 9800                 141       mov [sp+0x00], a
    00000019                      143       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    00000019 8800                 145       mov a, [sp+0x00]
    0000001B FC000000             146       call !!_R_DAC0_Set_ConversionValue
    0000001F C6                   147       pop hl
    00000020 D7                   148       ret
    00000021                      149       ;***       88 : }

    (2-B) プロジェクト作成時のデフォルトの最適化 ⇒ 0(0x00)も変数a+10(0x0A)も変数bへ代入していない

    00000009                      113  _test:
    00000009                      114       .STACK _test = 4
    00000009                      119       ;***       84 : void test(char a){
    00000009 0C0A                 121       add a, #0x0A
    0000000B                      122       ;***       85 :    /* volatile */ char b = 0;
    0000000B                      123       ;***       86 :     b = a+10;
    0000000B                      124       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    0000000B EC000000             126       br !!_R_DAC0_Set_ConversionValue
    0000000F                      127       ;***       88 : }

    (2-C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言 ⇒ 0(0x00)や変数a+10(0AH)を変数bへ代入している

    00000009                      113  _test:
    00000009                      114       .STACK _test = 6
    00000009                      119       ;***       84 : void test(char a){
    00000009 C7                   121       push hl (補)変数bの領域をスタック上に確保する
    0000000A                      122       ;***       85 :    volatile char b = 0;
    0000000A C80000               124       mov [sp+0x00], #0x00
    0000000D                      125       ;***       86 :     b = a+10;
    0000000D 0C0A                 127       add a, #0x0A
    0000000F 9800                 128       mov [sp+0x00], a
    00000011                      129       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    00000011 8800                 131       mov a, [sp+0x00]
    00000013 FC000000             132       call !!_R_DAC0_Set_ConversionValue
    00000017 C6                   133       pop hl
    00000018 D7                   134       ret
    00000019                      135       ;***       88 : }

     

Reply
  • SUZUKIさん、こんにちは。NoMaYです。すみません。夜遅くなるどころか日付まで変わってしまいました。

    CA78K0RとCC-RLでコンパイラが生成するコードを調べてみました。試したプロジェクトは以下のzipファイルに固めてあります。ただ、書いてみて思ったのですが、もっと分かり易く書き直さないと駄目な気がします。もう少し、書き方を考えてみようと思います。

    Issue_20171214.zip

    具体的には以下のソースコードに対して2×3=6つの条件でコンパイルして、コンパイルリストを出力させ、変数bへの代入がどうなっているかアセンブラコードを調べました。

    void test(char a){
        /* volatile */ char b = 0;
        b = a+10;
        R_DAC0_Set_ConversionValue(b);
    }

    (1) CA78K0R V1.72
    (2) CC-RL V1.02 (当方特有の事情で最新版では無いです)

    (A) 最適化なし
    (B) プロジェクト作成時のデフォルトの最適化
    (C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言

    今回の件は(1-B)に該当するのですが、わわいさんがアドバイスしている通り、最適化のため変数への値の代入がなされなかった、ということです。ただ、ちょっと紛らわしいことに、もう少しCA78K0Rが賢ければ多分なされなかったと思われる「0を代入する」ことは行われており、それに対して「a+10を代入する」ことだけが行われなくなっていたので、ということでした。(ちなみに、CC-RLでは「0を代入する」ことも行われなくなっていました。)

    (1) CS+ for CA,CX V4.00.01 + CA78K0R V1.72




    (1-A) 最適化なし ⇒ 0(00H)や変数a+10(0AH)を変数bへ代入している

      760   760                      ; line    83 : void test(char a){
      761   761 00012                _test:
      763   763 00012  C7                    push    hl                                              ;[INF] 1, 1
      764   764 00013  C1                    push    ax (補)引数aをスタックに移す                    ;[INF] 1, 1
      765   765 00014  C1                    push    ax (補)変数bの領域をスタック上に確保する        ;[INF] 1, 1
      766   766 00015  FBF8FF                movw    hl,sp                                           ;[INF] 3, 1
      768   768                      ; line    84 :     /* volatile */ char b = 0;
      770   770 00018  CC0100                mov     [hl+1],#00H     ; b,0                           ;[INF] 3, 1
      771   771                      ; line    85 :     b = a+10;
      773   773 0001B  8C02                  mov     a,[hl+2]        ; a                             ;[INF] 2, 1
      774   774 0001D  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      775   775 0001F  9C01                  mov     [hl+1],a        ; b                             ;[INF] 2, 1
      776   776                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      778   778 00021  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す   ;[INF] 2, 1
      779   779 00023 RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      780   780                      ; line    87 : }
      783   783 00027  1004                  addw    sp,#04H                                         ;[INF] 2, 1
      784   784 00029  C6                    pop     hl                                              ;[INF] 1, 1
      785   785 0002A  D7                    ret                                                     ;[INF] 1, 6

    (1-B) プロジェクト作成時のデフォルトの最適化 ⇒ 0(00H)を変数bへ代入しているが、変数a+10(0AH)を変数bへ代入していない

      759   759                      ; line    83 : void test(char a){
      760   760 00012                _test:
      762   762 00012  C7                    push    hl                                              ;[INF] 1, 1
      763   763 00013  16                    movw    hl,ax                                           ;[INF] 1, 1
      765   765                      ; line    84 :     /* volatile */ char b = 0;
      767   767 00014  5700                  mov     h,#00H  ; 0                                     ;[INF] 2, 1
      768   768                      ; line    85 :     b = a+10;
      770   770 00016  66                    mov     a,l                                             ;[INF] 1, 1
      771   771 00017  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      772   772                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      774   774 00019  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す     ;[INF] 2, 1
      775   775 0001B RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      776   776                      ; line    87 : }
      779   779 0001F  C6                    pop     hl                                              ;[INF] 1, 1
      780   780 00020  D7                    ret                                                     ;[INF] 1, 6

    (1-C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言 ⇒ 0(00H)や変数a+10(0AH)を変数bへ代入している

      759   759                      ; line    83 : void test(char a){
      760   760 00012                _test:
      762   762 00012  C7                    push    hl                                              ;[INF] 1, 1
      763   763 00013  C1                    push    ax (補)引数aをスタックに移す                   ;[INF] 1, 1
      764   764 00014  C1                    push    ax (補)変数bの領域をスタック上に確保する        ;[INF] 1, 1
      765   765 00015  FBF8FF                movw    hl,sp                                           ;[INF] 3, 1
      767   767                      ; line    84 :     volatile char b = 0;
      769   769 00018  CC0100                mov     [hl+1],#00H     ; b,0                           ;[INF] 3, 1
      770   770                      ; line    85 :     b = a+10;
      772   772 0001B  8C02                  mov     a,[hl+2]        ; a                             ;[INF] 2, 1
      773   773 0001D  0C0A                  add     a,#0AH  ; 10                                    ;[INF] 2, 1
      774   774 0001F  9C01                  mov     [hl+1],a        ; b                             ;[INF] 2, 1
      775   775                      ; line    86 :     R_DAC0_Set_ConversionValue(b);
      777   777 00021  8C01                  mov     a,[hl+1]        ; b                             ;[INF] 2, 1
      778   778 00023  318E                  shrw    ax,8 (補)AレジスタをAXレジスタ(引数)に移す     ;[INF] 2, 1
      779   779 00025 RFC000000              call    !!_R_DAC0_Set_ConversionValue                   ;[INF] 4, 3
      780   780                      ; line    87 : }
      783   783 00029  1004                  addw    sp,#04H                                         ;[INF] 2, 1
      784   784 0002B  C6                    pop     hl                                              ;[INF] 1, 1
      785   785 0002C  D7                    ret                                                     ;[INF] 1, 6

    (2) CS+ for CC V6.00.00 + CC-RL V1.02




    (2-A) 最適化なし ⇒ 0(0x00)や変数a+10(0x0000A)を変数bへ代入している

    00000009                      121  _test:
    00000009                      122       .STACK _test = 6
    00000009                      127       ;***       84 : void test(char a){
    00000009 C7                   129       push hl (補)引数aと変数bの領域をスタック上に確保する
    0000000A 9801                 130       mov [sp+0x01], a (補)引数aをスタックに移す
    0000000C                      131       ;***       85 :    /* volatile */ char b = 0;
    0000000C C80000               133       mov [sp+0x00], #0x00
    0000000F                      135       ;***       86 :     b = a+10;
    0000000F 8801                 137       mov a, [sp+0x01]
    00000011 318E                 138       shrw ax, 8+0x00000 (補)AレジスタをAXレジスタ(作業用)に移す
    00000013 040A00               139       addw ax, #0x000A
    00000016 60                   140       mov a, x
    00000017 9800                 141       mov [sp+0x00], a
    00000019                      143       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    00000019 8800                 145       mov a, [sp+0x00]
    0000001B FC000000             146       call !!_R_DAC0_Set_ConversionValue
    0000001F C6                   147       pop hl
    00000020 D7                   148       ret
    00000021                      149       ;***       88 : }

    (2-B) プロジェクト作成時のデフォルトの最適化 ⇒ 0(0x00)も変数a+10(0x0A)も変数bへ代入していない

    00000009                      113  _test:
    00000009                      114       .STACK _test = 4
    00000009                      119       ;***       84 : void test(char a){
    00000009 0C0A                 121       add a, #0x0A
    0000000B                      122       ;***       85 :    /* volatile */ char b = 0;
    0000000B                      123       ;***       86 :     b = a+10;
    0000000B                      124       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    0000000B EC000000             126       br !!_R_DAC0_Set_ConversionValue
    0000000F                      127       ;***       88 : }

    (2-C) プロジェクト作成時のデフォルトの最適化で変数bをvolatile宣言 ⇒ 0(0x00)や変数a+10(0AH)を変数bへ代入している

    00000009                      113  _test:
    00000009                      114       .STACK _test = 6
    00000009                      119       ;***       84 : void test(char a){
    00000009 C7                   121       push hl (補)変数bの領域をスタック上に確保する
    0000000A                      122       ;***       85 :    volatile char b = 0;
    0000000A C80000               124       mov [sp+0x00], #0x00
    0000000D                      125       ;***       86 :     b = a+10;
    0000000D 0C0A                 127       add a, #0x0A
    0000000F 9800                 128       mov [sp+0x00], a
    00000011                      129       ;***       87 :     R_DAC0_Set_ConversionValue(b);
    00000011 8800                 131       mov a, [sp+0x00]
    00000013 FC000000             132       call !!_R_DAC0_Set_ConversionValue
    00000017 C6                   133       pop hl
    00000018 D7                   134       ret
    00000019                      135       ;***       88 : }

     

Children
No Data