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_t
que desplazo un poco a la derecha en cada iteración usando data >>= 1
y parece que el compilador tradujo esto en 5 instrucciones ( data
está 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 r18
y r19
no se utilizan en ningún otro lugar.
Estoy usando un Ardunio, pero si estoy en lo correcto, solo uso el avr-gcc
compilador 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-objdump
en 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 casoint
es de 16 bits de ancho) involucrado en cualquier operación (en su caso>>
) se convierte en unint
antes de la operación.Este comportamiento del compilador se llama promoción de enteros .
Y eso es exactamente lo que hizo el compilador:
data
.data
ese valor que luego se desplaza un bit hacia la derecha porasr r19
yror 18
.uint8_t
variabledata
:mov r24, r18
es 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 r24
instrucción. Entonces, tal vez esté utilizando una versión compiladora muy antigua.fuente
d >>= 1;
solo recibo una solalsr r24
instrucción. Quizás xZise está utilizando una versión de compilador muy antigua.