Hola, he estado trabajando en un proyecto utilizando un Arduino Uno (entonces ATmega328p) donde el tiempo es bastante importante y quería ver en qué instrucciones el compilador estaba convirtiendo mi código. Y allí tengo una uint8_tque desplazo un poco a la derecha en cada iteración usando data >>= 1y parece que el compilador tradujo esto en 5 instrucciones ( dataestá en r24):
mov r18, r24
ldi r19, 0x00
asr r19
ror r18
mov r24, r18
Pero si miro la documentación del conjunto de instrucciones, veo una instrucción que hace exactamente esto: lsr r24
¿Puedo pasar por alto algo o por qué el compilador no está usando esto también? Los registros r18y r19no se utilizan en ningún otro lugar.
Estoy usando un Ardunio, pero si estoy en lo correcto, solo uso el avr-gcccompilador normal . Este es el código (recortado) que genera la secuencia:
ISR(PCINT0_vect) {
uint8_t data = 0;
for (uint8_t i = 8; i > 0; --i) {
// asm volatile ("lsr %0": "+w" (data));
data >>= 1;
if (PINB & (1 << PB0))
data |= 0x80;
}
host_data = data;
}
Por lo que puedo ver, el IDE de Ardunino está utilizando el compilador AVR gcc proporcionado por el sistema, que es la versión 6.2.0-1.fc24. Ambos se instalan a través del administrador de paquetes, por lo que deben estar actualizados.

avr-objdumpen el archivo elfo ... ¿Qué es lo que parece no corresponder?data >>= 1;Respuestas:
De acuerdo con la especificación del lenguaje C, cualquier valor cuyo tamaño sea menor que el tamaño de
int(depende del compilador particular; en su casointes de 16 bits de ancho) involucrado en cualquier operación (en su caso>>) se convierte en unintantes de la operación.Este comportamiento del compilador se llama promoción de enteros .
Y eso es exactamente lo que hizo el compilador:
data.dataese valor que luego se desplaza un bit hacia la derecha porasr r19yror 18.uint8_tvariabledata:mov r24, r18es decir, se desecha el MSByte en r19.Editar: por
supuesto, el cumplidor podría optimizar el código.
Intentando reproducir el problema, descubrí que al menos con avr-gcc versión 4.9.2 el problema no ocurre. Crea un código muy eficiente, es decir, C-line
data >>= 1;se compila en una solalsr r24instrucción. Entonces, tal vez esté utilizando una versión compiladora muy antigua.fuente
d >>= 1;solo recibo una solalsr r24instrucción. Quizás xZise está utilizando una versión de compilador muy antigua.