ループが離れて最適化されている間


8

マイクロコントローラープログラムに次のコードがあります。

// Wait for ADC conversion to complete
while ( ( ADCSRA && _BS( ADSC ) ) == _BS( ADSC ) ) {}

ADCSRAは、アナログ変換が完了するとその値を変更するレジスタであり、ビットがクリアされるのを待ちたい場所です。このビットは、変換が完了したことを示します。

結果のアセンブリコードを見ると、ループ全体が1つの命令に置き換えられています。

in      r24, 0x06       ; ADCSRA

レジスタは読み込まれますが、その値はテストされていません!?

プログラムを不必要に遅延させることなく、レジスターを再チェックし続けるようコンパイラーに指示するには、C ++コードをどのように変更する必要がありますか?

私はavr-gccツールチェーンを使用しています。

編集: 私は次のようにコードを変更しました(Thnx:lhballoti):

while ( ( ADCSRA & _BS( ADSC ) ) == _BS( ADSC ) ) {}

アセンブリコードが次のように変更されました。

38:   36 99           sbic    0x06, 6         ; 6
3a:   fe cf           rjmp    .-4             ; 0x38 <__CCP__+0x4>

どちらが問題を問題なく解決したか。

完全なプログラムとその逆アセンブルされたコードについては、このページを確認しください。


3
ビット単位のANDを使用するつもりはありませんか?
lhballoti

通常、あなたは、揮発するレジスタを宣言した後、どこループでしょうあなたは物事が最適化されることはありません...しかし、それはファイルが含まれであなたのために行われるべきで変更しないでください。
W5VO 2012

私はすぐに間違いを見つけましたが、コンパイラーが最初のケースでループをすぐに最適化した理由を理解できません。もしはADCSRA、揮発性ではなく、また、同じ最適化の対象に第二の場合ではないのですか?
lhballoti

質問を回答で編集するのではなく、誰かの回答を受け入れるか、独自の回答を書いて同意してください。
Kellenjb

@Kellenjb-ジッピーが答えになる前に追加しました。lhballotiは最初にコメントとしてそれを与えた。
stevenvh 2012

回答:


11

ビットごとのANDを使用する必要があります。最初のwhileループの式はゼロと評価され、コンパイラーはループを完全に削除します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.