Sementara loop dioptimalkan


8

Saya memiliki kode berikut dalam program mikrokontroler saya:

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

Di mana ADCSRA adalah register yang akan mengubah nilainya begitu konversi analog selesai dan di mana saya ingin menunggu sedikit menjadi jelas. Bit ini menunjukkan konversi selesai.

Melihat kode perakitan yang dihasilkan, seluruh loop diganti dengan satu instruksi:

in      r24, 0x06       ; ADCSRA

Register sudah dibaca, tetapi nilainya bahkan belum diuji !?

Bagaimana saya harus mengubah kode C ++ saya untuk menginstruksikan kompiler untuk terus memeriksa ulang register, tanpa menunda program?

Saya menggunakan toolchain avr-gcc.

EDIT: Saya mengubah kode sebagai berikut (Thnx: lhballoti):

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

Yang mengubah kode perakitan menjadi:

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

Yang benar-benar memecahkan masalah.

Periksa halaman ini untuk mengetahui program yang lengkap dan kode yang dihasilkan yang dibongkar.


3
Apakah Anda tidak bermaksud menggunakan bitwise AND?
lhballoti

biasanya Anda akan mendeklarasikan register sebagai volatile, dan kemudian loop di mana Anda tidak memodifikasi hal-hal tidak akan dioptimalkan ... tapi itu harus dilakukan untuk Anda dalam file include.
W5VO

Walaupun saya langsung menemukan kesalahan, saya mengalami kesulitan memahami mengapa kompiler mengoptimalkan loop jauh dalam kasus pertama. Jika ADCSRAtidak stabil, bukankah huruf kedua juga mengalami optimasi yang sama?
lhballoti

Anda tidak boleh mengedit pertanyaan Anda dengan jawabannya, daripada menerima jawaban seseorang atau menulis jawaban Anda sendiri dan menerimanya.
Kellenjb

@Kellenjb - jippie menambahkannya sebelum jawabannya. lhballoti pertama hanya memberikannya sebagai komentar.
stevenvh

Jawaban:


11

Anda harus menggunakan bitwise AND. Ekspresi di whileloop pertama mengevaluasi ke nol, yang menyebabkan kompiler untuk menghapus loop sama sekali.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.