Oi Eu estive trabalhando em um projeto usando um Arduino Uno (então ATmega328p), onde o tempo é muito importante e, portanto, eu queria ver em quais instruções o compilador estava convertendo meu código. E aí eu tenho um uint8_t
que eu desloco um pouco para a direita em cada iteração usando data >>= 1
e parece que o compilador traduziu isso em 5 instruções ( data
está em r24
):
mov r18, r24
ldi r19, 0x00
asr r19
ror r18
mov r24, r18
Mas se eu olhar para a documentação do conjunto de instruções, vejo uma instrução que faz exatamente isso: lsr r24
Eu negligencio algo ou por que o compilador não está usando isso também? Os registradores r18
e r19
não são usados em nenhum outro lugar.
Estou usando um Ardunio, mas se estiver correto, basta usar o avr-gcc
compilador normal . Este é o código (aparado) que gera a sequência:
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;
}
Tanto quanto posso ver, o Ardunino IDE está usando o compilador AVR gcc fornecido pelo sistema, versão 6.2.0-1.fc24. Ambos são instalados através do gerenciador de pacotes, portanto, devem estar atualizados.
avr-objdump
no arquivo elf ... O que parece não corresponder?data >>= 1;
Respostas:
De acordo com a especificação da linguagem C, qualquer valor cujo tamanho seja menor que o tamanho
int
(depende do compilador específico; no seu casoint
tem 16 bits de largura) envolvido em qualquer operação (no seu caso>>
) é upcast para umint
antes da operação.Esse comportamento do compilador é chamado de promoção inteira .
E foi exatamente isso que o compilador fez:
data
.data
que é então deslocado para a direita um bit porasr r19
eror 18
.uint8_t
variáveldata
:mov r24, r18
, ou seja, o MSByte em R19 é jogado fora.Editar:
é claro que o complier pode otimizar o código.
Tentando reproduzir o problema, descobri que, pelo menos com a versão 4.9.2 do avr-gcc, o problema não ocorre. Ele cria código muito eficiente, ou seja, a linha C
data >>= 1;
é compilada em apenas uma únicalsr r24
instrução. Talvez você esteja usando uma versão do compilador muito antiga.fonte
d >>= 1;
recebo apenas uma únicalsr r24
instrução. Talvez o xZise esteja usando uma versão do compilador muito antiga.