J'utilise actuellement l'ASM inline suivant pour que le Cortex-M3 se branche sur une adresse spécifique en flash.ASM en ligne - Utiliser une variable C de 16 ou 32 bits (GCC ARM, mode Thumb)
__asm("LDR R0, =0x8000"); // Load the branch address
__asm("LDR R1, [R0]"); // Get the branch address
__asm("ORR R1, #1"); // Make sure the Thumb State bit is set.
__asm("BX R1"); // Branch execution
- Cependant, je veux remplacer la valeur codée en dur
0x8014
avec une variable C qui sera calculé en fonction de certaines autres conditions. - La plus grande valeur possible que cette variable peut prendre est 0x20000, donc j'avais prévu d'utiliser un
uint32_t
pour le stocker. - Le compilateur utilisé est
arm-none-eabi-gcc
v4.9.3
J'ai essayé de modifier mon ASM en ligne comme suit:
uint32_t destination_address = 0x8000;
__asm("LDR R0, =%[dest]" : : [dest]"r"(destination_address));
Cependant, cela génère l'erreur du compilateur:
undefined reference to `r3'
Je suis relativement nouveau à l'ASM en ligne en général. J'ai essayé de rechercher ce problème pendant deux jours, mais j'ai été troublé par des réponses contradictoires en raison de la diversité des compilateurs et du fait que j'utilise des instructions Thumb pour le Cortex-M3.
Je pense mon problème est que je dois trouver la contrainte correcte pour la destination_address
variable (gamme 0x0 - 0x20000), mais je ne suis pas sûr.
Les bonnes nouvelles sont que l'erreur est facile à corriger (https://godbolt.org/g/3B9YqC). Si vous allez utiliser inline asm, vous devriez vous habituer à utiliser '-S' (c'est ce que Godbolt utilise ici). L'inconvénient est que gcc n'aime pas quand vous faites des sauts dans l'asm. Cela peut vraiment gâcher l'optimisation, les refs de symboles, etc. –
@DavidWohlferd Je ne suis pas tout à fait sûr que je suis. (i) Réécrire =% [dest] car [% [dest]] permet de compiler le code, selon votre exemple lié! (ii) Mais je ne comprends pas pourquoi?(iii) Que signifie «-S» et plus important encore, où se manifeste-t-il dans votre exemple? (iv) Vous devriez poster ceci comme réponse! (v) En ce qui concerne le saut de l'ASM, dans ce cas d'utilisation je quitte le binaire et je ne reviendrai jamais. – msolters
ii) Comme vous pouvez le voir sur la sortie, 0x8000 est déplacé dans le registre r3 (ce que vous avez fait avec 'LDR R0, = 0x8000'). Votre deuxième ligne ('LDR R1, [R0]') suppose que la valeur est dans r0, mais en utilisant la contrainte "r", gcc peut choisir n'importe quel registre disponible. Plutôt que de deviner ou de supposer, nous substituons s/R0 /% [dest]. Une réponse plus directe serait que faire '=% [dest]' va s'étendre à '= r3', ce qui ne me semble pas être un assembleur valide. iii) -S est documenté ici (https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#index-S-83). –