Question

Ceci est un extrait de code AVR démontées à partir d'un projet C je travaille. J'ai remarqué ce code curieux généré, et je ne peux pas comprendre comment cela fonctionne. Je suppose que c'est une sorte d'optimisation ridicule ...

Quelle est l'explication?

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

Plus précisément, pourquoi la deuxième Soustraire d'instruction de 0xFF R25 au lieu de simplement INC R25?

Était-ce utile?

La solution

L'instruction SUBI peut être utilisé pour ajouter / soustraire les 8 bits constant vers / à partir d'une valeur de 8 bits. Il a le même coût que INC, à savoir la taille de l'instruction et le temps d'exécution. Alors SUBI est préféré par le compilateur car il est plus général. Il n'y a pas d'instruction ADDI correspondante, probablement parce qu'il serait superflu.

Autres conseils

tl;. Dr le compilateur a été conçu pour utiliser la solution plus portable, efficace et général ici

SUBI instruction active C (carry) et H ( demi-carry) flags CPU pour une utilisation avec les instructions suivantes (il n'y a pas ADDI dans AVR 8 bits BTW, afin d'ajouter une valeur immédiate de x nous soustrayons -x de celui-ci), alors que INC ne fonctionne pas. Depuis les deux SUBI et INC ont 2 octets de longueur et exécuter pendant 1 cycle d'horloge, vous ne perdez rien en utilisant SUBI - OTOH, si vous utilisez une contre-taille 8 bits, vous pouvez facilement détecter si elle a roulé sur (par < a href = "http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_BRCC.html" rel = "nofollow noreferrer"> BRCC / BRCS ), et si vous avez un contre-taille 32 bits ou 16-, il vous permet d'incrémenter en d'une manière très simple - avec juste INC, 0x00FF se serait passé à 0x0000, de sorte que vous auriez à vérifier si l'octet le plus bas est 0xFF avant INCing. OTOH, avec SUBI vous venez SUBI -1 l'octet le plus bas, puis ADC 0 pour les octets suivants, assurant tous les bits de report potentiels a été pris en compte.

Pour en savoir plus:

https: //lists.gnu .org / archive / html /-gcc-AVR liste / 2008-11 / msg00029.html

http: //-gcc-AVR liste .nongnu.narkive.com / SMMzdBkW / foo-Subi-vs-inc

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top