藤田様の別スレッドに便乗なのですが、CS+のRL78のコード生成ツールが生成するuart通信機能のポインタ変数でvolatile修飾子の記述位置がおかしいものがあるように思います。具体的な変数名で言うと、gp_uart0_tx_addressとgp_uart0_rx_addressです。(CS+ for CC V5.00.00のコード生成機能で確認しました。)コード生成ツールが生成した変数宣言は以下の通りです。volatile uint8_t * gp_uart0_tx_address; /* uart0 send buffer address */volatile uint8_t * gp_uart0_rx_address; /* uart0 receive buffer address */ところが、以下の画面コピーの赤枠の箇所の通り、割り込みルーチン内で変更されるのはgp_uart0_tx_addressやgp_uart0_rx_addressの変数自身ですので以下の変数宣言が正しい気がします。uint8_t * volatile gp_uart0_tx_address; /* uart0 send buffer address */uint8_t * volatile gp_uart0_rx_address; /* uart0 receive buffer address */試しに型修飾子の作用の仕方がvolatileと同様なconst(型修飾子の作用自体(機能)としては対義語的になる)で試してみると、変数自身に作用したのは以下の画面コピーのように橙枠の方でしたので、volatileも変数自身に作用させる場合には同様である筈です。
でも、わわいさん、RL78やRXの話にいつもいつもSHの話を持ち出されてますよね?(しかも、頻繁に他の人にRL78やRXでは話が違うと誤りを指摘されていて。)(さらに、誤りを指摘されても、意固地なまでに反論されることは有っても、素直に間違いを詫びる返事をされたことが無いという。)さすがに、あなたがそれを言いますか?という思いです、、、
わわいさんwrote: said:わわいです いや、元質問のトピックにわざわざGCCもってこられましても。。
> いや、元質問のトピックにわざわざGCCもってこられましても。。
では CC-RL V1.04.00 を使用して最適化の指定を「実効速度優先(-Ospeed)」にしてコンパイルした結果をどうぞ。
extern volatile int* hogehoge; void hoge(void) { while (*hogehoge) { ; } } void hogera(void) { while (hogehoge) { ; } } extern int* volatile piyopiyo; void piyo(void) { while (*piyopiyo) { ; } } void piyora(void) { while (piyopiyo) { ; } }
_hoge: movw bc, !LOWW(_hogehoge) .BB@LABEL@2_1: ; bb1 movw ax, 0x0000[bc] or a, x bnz $.BB@LABEL@2_1 ret _hogera: movw ax, !LOWW(_hogehoge) or a, x sknz ret .BB@LABEL@3_2: ; bb1 br $.BB@LABEL@3_2 _piyo: .BB@LABEL@4_1: ; bb1 movw bc, !LOWW(_piyopiyo) movw ax, 0x0000[bc] or a, x bnz $.BB@LABEL@4_1 ret _piyora: .BB@LABEL@5_1: ; bb1 movw ax, !LOWW(_piyopiyo) or a, x bnz $.BB@LABEL@5_1 ret
リカルドさん、こんにちは。藤田様、フォロー有難う御座います。
リカルドさまwrote: said:>1 void hoge(void) 2 { 3 extern volatile int* hogehoge; 4 while (*hogehoge) ; 7 while (hogehoge) ; 10 } hoge: movq .refptr.hogehoge(%rip), %rax movq (%rax), %rdx .L2: while (*hogehoge)に相当 movl (%rdx), %eax testl %eax, %eax jne .L2 .L3: while (hogehoge)に相当 jmp .L3 hogehoge がゼロでない事を何処で判断したの? .text
リカルドさまwrote: said:>NULL は何のオブジェクトも指しませんが、逆に、何かのオブジェクトを指すポインタは NULL でないことは確定的です。前段の hogehoge の指す先をアクセスした以降では hogehoge の値は NULL ではないということで、無限ループとなります。 NULL だったら関数を抜けると言う判断をどこかでしているのなら分かります。 しかし、そんな事はしていないよね。 NULL かどうか判断して、「NULLでした」と表示するプログラムは作れないと言うこと? ...略... コンパイルの動作がおかしいんじゃないかと言う話です。
> 薄青の画面はどうやって作るのですか?
投稿の際に'Use rich formatting' を選び、「Tools」→「<> Source code」を選択して HTML 編集を行い、コードは <pre> ~ </pre> で囲んでいます。
> NULL だったら関数を抜けると言う判断をどこかでしているのなら分かります。
> しかし、そんな事はしていないよね。
明示的に NULL チェックを行い、ポインタの値が NULL である可能性があることをコンパイラに伝えれば NULL だった場合は安全に関数を抜けるコードを吐きますよ。
$ cat -n hoge.c 1 void hoge(void) 2 { 3 extern volatile int* hogehoge; 4 if (hogehoge) { 5 while (*hogehoge) { 6 ; 7 } 8 } 9 while (hogehoge) { 10 ; 11 } 12 } $ gcc -Wall -W -S -O2 hoge.c -o - .text hoge: movq .refptr.hogehoge(%rip), %rax movq (%rax), %rdx testq %rdx, %rdx je .L1 .L5: movl (%rdx), %eax testl %eax, %eax jne .L5 .L4: jmp .L4 .L1: rep ret $
解説をすると、
extern volatile int* hogehoge;
void hoge(void) { while (*hogehoge) { ; } }
_hoge: movw bc, !LOWW(_hogehoge) ; _hogehoge の値値を BC に読み出し .BB@LABEL@2_1: ; bb1 movw ax, 0x0000[bc] ; BC の指すアドレスから 2バイトを AX に読み出し or a, x ; A に X を OR し、AX が 0 かを判定 bnz $.BB@LABEL@2_1 ; 0 でなければ .BB@LABEL@2_1 に分岐 ret ; 復帰
void hogera(void) { while (hogehoge) { ; } }
_hogera: movw ax, !LOWW(_hogehoge) ; _hogehoge の値値を AX に読み出し or a, x ; A に X を OR し、AX が 0 かを判定 sknz ; 0 でなければ次の命令を実行しない ret ; (AX が 0であれば)復帰 .BB@LABEL@3_2: ; bb1 br $.BB@LABEL@3_2 ; .BB@LABEL@3_2 に分岐(無限ループ)
extern int* volatile piyopiyo;
void piyo(void) { while (*piyopiyo) { ; } }
_piyo: .BB@LABEL@4_1: ; bb1 movw bc, !LOWW(_piyopiyo) ; _hogehoge の値値を BC に読み出し movw ax, 0x0000[bc] ; BC の指すアドレスから 2バイトを AX に読み出し or a, x ; A に X を OR し、AX が 0 かを判定 bnz $.BB@LABEL@4_1 ; 0 でなければ .BB@LABEL@2_1 に分岐 ret ; 復帰
void piyora(void) { while (piyopiyo) { ; } }
_piyora: .BB@LABEL@5_1: ; bb1 movw ax, !LOWW(_piyopiyo) ; _hogehoge の値値を AX に読み出し or a, x ; A に X を OR し、AX が 0 かを判定 bnz $.BB@LABEL@5_1 ; 0 でなければ .BB@LABEL@5_1 に分岐 ret ; 復帰