Porque é que este código que está sendo gerado por avr-gcc e como ele funciona?

votos
4

Este é um trecho de código AVR desmontado a partir de um projeto de C Eu estou trabalhando. Eu observei este código curioso que está sendo gerado, e eu não consigo entender como ele funciona. Eu estou assumindo que é algum tipo de otimização ridículo ...

Qual é a explicação?

92:         ticks++;         // unsigned char ticks;
+0000009F:   91900104    LDS       R25,0x0104     Load direct from data space
+000000A1:   5F9F        SUBI      R25,0xFF       Subtract immediate
+000000A2:   93900104    STS       0x0104,R25     Store direct to data space
95:         if (ticks == 0) {
+000000A4:   2399        TST       R25            Test for Zero or Minus
+000000A5:   F009        BREQ      PC+0x02        Branch if equal
+000000A6:   C067        RJMP      PC+0x0068      Relative jump

Especificamente, por que a segunda instrução subtrair 0xFF de R25 em vez de apenas INC R25?

Publicado 26/08/2009 em 23:13
fonte usuário
Em outras línguas...                            


2 respostas

votos
4

A instrução SUBI pode ser usado para adicionar / subtrair qualquer 8 bits constante de / para um valor de 8 bits. Ele tem o mesmo custo que INC, ou seja, o tamanho de instrução e tempo de execução. Então SUBI é o preferido pelo compilador porque é mais geral. Não há nenhuma instrução ADDI correspondente, provavelmente porque seria redundante.

Respondeu 27/08/2009 em 06:53
fonte usuário

votos
3

tl; dr o compilador foi projetado para usar a solução geral mais portátil, eficiente e aqui.

Os SUBIconjuntos de instruções C(carry) e H(half-carry) bandeiras da CPU para uso com instruções subseqüentes (não existe ADDIem 8 bits AVR BTW, de modo a adicionar um valor imediato de xsubtraímos -xa partir dele), enquanto INCnão. Uma vez que tanto SUBIe INCtem 2 bytes de comprimento e executar durante 1 ciclo de clock, você não perde nada usando SUBI- OTOH, se você usar um contador de 8 bits de tamanho, então você pode facilmente detectar se ele rolou (por BRCC/ BRCS), e Se você tem um contador de 16 ou 32 bits de tamanho, que lhe permite incrementar isso de uma maneira muito simples - com apenas INC, 0x00FFiria ficar aumentou para 0x0000, então você tem que verificar se o menor byte é 0xFFantes INCing . OTOH, comSUBIvocê apenas SUBI -1o menor byte, e depois ADC 0para os seguintes bytes, garantindo foi contabilizados todos os potenciais pedaços carry.

Outras leituras:

https://lists.gnu.org/archive/html/avr-gcc-list/2008-11/msg00029.html

http://avr-gcc-list.nongnu.narkive.com/SMMzdBkW/foo-subi-vs-inc

Respondeu 26/08/2009 em 23:27
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more