10 votos

¿Por qué no el compilador utilizar directamente LSR

Hola, he estado trabajando en un proyecto usando un Arduino Uno (por lo ATmega328p) donde el tiempo es muy importante y por eso quería ver en que las instrucciones que el compilador era la conversión de mi código. Y ahí tengo un uint8_t que me cambio un poco a la derecha en cada iteración usando data >>= 1 y parece que el compilador traduce esto en 5 instrucciones (data en r24):

mov     r18, r24
ldi     r19, 0x00
asr     r19
ror     r18
mov     r24, r18

Pero si miro en el conjunto de instrucciones de la documentación que yo veo una instrucción que hace exactamente esto: lsr r24

Puedo pasar por alto algo o ¿por qué no el compilador mediante esta así? Los registros r18 y r19 no se utiliza en ningún otro lugar.

Estoy usando un Ardunio pero si estoy en lo correcto es usar el normal avr-gcc del compilador. 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;
}

Tan lejos como puedo ver el Ardunino IDE es utilizar el AVR gcc compiler proporcionada por el sistema que es la versión 6.2.0-1.fc24. Ambos están instalados a través del paquete pesebre así debe ser hasta la fecha.

18voto

krgrant Puntos 11

De acuerdo con C la especificación del lenguaje de cualquier valor, cuyo tamaño es menor que el tamaño de int (depende del compilador; en su caso int es de 16 bits de ancho) que intervienen en cualquier operación (en su caso >>) es upcast a un int antes de la operación.
Este comportamiento del compilador se llama entero de la promoción.

Y eso es exactamente lo que hace el compilador:

  • r19=0 es la MSByte del entero promovido valor de data.
  • (r19, r18) representa el total de número entero promovido valor de data que se desplaza a la derecha un bit por asr r19 y ror 18.
  • El resultado es entonces implícitamente elenco de regreso a su uint8_t variable data:
    mov r24, r18, es decir, el MSByte en r19 es echado fuera.

Editar:
Por supuesto, el compilador podría optimizar el código.
Tratando de reproducir el problema que he encontrado que, al menos, con el avr-gcc versión 4.9.2 no se produce el problema. Se crea un código eficiente, es decir, C-line data >>= 1; se compila a un solo lsr r24instrucción. Así que tal vez usted está utilizando una vieja versión del compilador.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X