Mientras que el bucle está optimizado

8

Tengo el siguiente código en mi programa de microcontrolador:

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

Donde ADCSRA es un registro que cambiará su valor una vez que se complete una conversión analógica y donde quiera esperar un poco para que quede claro. Este bit indica que la conversión se completó.

Mirando el código de ensamblaje resultante, todo el bucle se reemplaza por una sola instrucción:

in      r24, 0x06       ; ADCSRA

¿El registro se lee, pero su valor ni siquiera se prueba?

¿Cómo tengo que cambiar mi código C ++ para indicarle al compilador que vuelva a verificar el registro, sin retrasar innecesariamente el programa?

Yo uso la cadena de herramientas avr-gcc.

EDITAR: cambié el código de la siguiente manera (Thnx: lhballoti):

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

Que cambió el código de ensamblaje a:

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

Lo que aparentemente resuelve el problema.

Consulte esta página para ver el programa completo y su código resultante desmontado.

jippie
fuente
3
¿No quieres usar un AND bit a bit?
lhballoti
por lo general se declararían los registros a ser volátiles, y luego bucles en que no modifique las cosas no serán optimizados ... pero que se debe hacer para usted en los archivos de inclusión.
W5VO
Aunque descubrí el error de inmediato, tengo problemas para entender por qué el compilador optimizó el bucle en el primer caso. Si ADCSRAno es volátil, ¿el segundo caso tampoco está sujeto a la misma optimización?
lhballoti
No debe editar su pregunta con la respuesta, sino aceptar la respuesta de alguien o escribir su propia respuesta y aceptarla.
Kellenjb
@Kellenjb - jippie lo agregó antes de que fuera una respuesta. lhballoti primero solo lo dio como comentario.
stevenvh

Respuestas:

11

Debería estar utilizando un AND bit a bit. La expresión en el primer whilebucle se evalúa a cero, lo que hace que el compilador elimine el bucle por completo.

lhballoti
fuente