J'ai programmé le bras/pouce pendant beaucoup d'années beaucoup d'assembleur et ai eu besoin de très peu des nombreuses directives là-bas.
.thumb_func est assez important comme l'a souligné un autre répondant.
par exemple
.globl _start
_start:
b reset
reset:
.arm
.globl one
one:
add r0,r0,#1
bx lr
.thumb
.globl two
two:
add r0,r0,#2
bx lr
.thumb_func
.globl three
three:
add r0,r0,#3
bx lr
.word two
.word three
.arm ou utilisé pour quelque chose comme .code32 ou 32 .code dit qu'il est ce code bras pas de code de pouce, qui pour votre cortex m3 vous n'aurez pas besoin d'utiliser. De même, utilisé pour être .code 16 ou peut-être que cela fonctionne encore, la même donne le pouce de code suivant pas armer. Si les étiquettes que vous utilisez ne sont pas des étiquettes globales à partir desquelles vous devez vous connecter à partir d'autres fichiers ou indirectement, alors vous n'avez pas besoin du .thumb_func. Mais pour que l'adresse d'une branche à l'une de ces étiquettes globales soit calculée correctement (lsbit est un 1 pour le pouce et 0 pour le bras) vous voulez le marquer comme un pouce ou bras étiquette et le thumb_func fait cela, sinon vous doivent définir que peu avant de ramification en ajoutant plus de code et le marqueur est pas appelable à partir de C.
00000000 <_start>:
0: eaffffff b 4 <one>
00000004 <one>:
4: e2800001 add r0, r0, #1
8: e12fff1e bx lr
0000000c <two>:
c: 3002 adds r0, #2
e: 4770 bx lr
00000010 <three>:
10: 3003 adds r0, #3
12: 4770 bx lr
14: 0000000c andeq r0, r0, ip
18: 00000011 andeq r0, r0, r1, lsl r0
jusqu'à la .thumb l'assembleur est un code de bras comme on le souhaite.
Les deux et trois étiquettes/fonctions sont du code pouce comme souhaité, mais les deux étiquettes ont une adresse paire et trois ont l'adresse impaire correcte.
Les derniers outils de codesurcery ont été utilisés pour assembler, lier et vider l'échantillon ci-dessus. Maintenant, pour le cortex-m3 où tout est pouce (/ thumb2) thumb_func peut ne pas être aussi important, il peut juste travailler avec des commutateurs de ligne de commande (très facile à faire une expérience pour le savoir). C'est une bonne habitude d'avoir cependant au cas où vous vous éloignez d'un processeur de pouce seulement à un noyau normal de bras/pouce.
Les monteurs aiment généralement ajouter toutes ces directives et d'autres façons de faire ressembler les choses/se sentir plus comme un langage de haut niveau. Je dis juste que vous ne devez pas les utiliser, j'ai changé les assembleurs pour le bras et utiliser beaucoup d'assembleurs différents pour beaucoup de processeurs différents et préférer l'approche moins, ce qui signifie se concentrer sur l'assemblage lui-même et utiliser le moins d'outils possible. Cependant, je suis généralement l'exception, pas la règle, donc vous pouvez probablement comprendre les directives les plus souvent utilisées en regardant quelles directives la sortie du compilateur génère (et vérifier avec la documentation).
unsigned int one (unsigned int x)
{
return(x+1);
}
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.file "bob.c"
.text
.align 2
.global one
.type one, %function
one:
.fnstart
.LFB0:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add r0, r0, #1
bx lr
.fnend
.size one, .-one
.ident "GCC: (Sourcery G++ Lite 2010.09-50) 4.5.1"
.section .note.GNU-stack,"",%progbits
J'utilise le .ALIGN lors du mélange bras et assembleur pouce ou données avec l'assembleur, vous attendez l'assembleur pour une telle plate-forme de savoir quelque chose d'aussi évident que les instructions du pouce sont sur les limites demi-mots et des instructions de bras sont aligné sur les limites de mots. Les outils ne sont pas toujours aussi intelligents. saupoudrer .aligns à propos de ne pas blesser
.text est la valeur par défaut donc c'est un peu redondant, mais pas blessé. .text et .data sont des attributs standard (non spécifiques à arm) si vous compilez pour une combinaison de rom et ram sur votre cible, cela peut vous intéresser (cela dépend de ce que vous faites avec votre script de linker), sinon .text fonctionnera pour tout .
.size apparemment la taille de la fonction commence à cette directive. L'assembleur ne peut pas le comprendre par lui-même, donc si la taille de cette fonction est importante pour votre code, script d'éditeur de liens, débogueur, loader, quoi que ce soit alors cela doit être correct, sinon vous n'avez pas à vous embêter. Une fonction est un concept de haut niveau de toute façon l'assembleur n'a pas vraiment de fonctions bien moins besoin de déclarer leur taille. Et le compilateur C ne s'en soucie certainement pas, il cherche seulement une étiquette à ramifier et dans le cas de la famille des bras, c'est le code pouce ou le code de bras qui est en train d'être ramifié.
vous pouvez trouver la directive .pool (il existe un équivalent plus récent) utile si vous êtes paresseux avec vos immédiates (ldr rx, = 0x12345678) sur de longues périodes de code. Là encore, les outils ne sont pas toujours assez intelligents pour placer ces données après une branche inconditionnelle, vous leur dites parfois. Je dis la moitié paresseux sérieusement, il est douloureux de faire l'étiquette: .word chose tout le temps et je crois que les deux outils de bras et gcc ont permis pour ce raccourci, donc je l'utilise autant que quelqu'un d'autre. Notez également que llvm génère un autre attribut .eabi_attribute ou deux qui est supporté par la version/mods de la sourcery du code vers binutils mais qui n'est pas supporté (peut-être encore) par binutils gnu. Deux solutions qui fonctionnent, modifient la fonction d'impression asm de llvm pour ne pas écrire les attributs eabi_attributes ou au moins les écrire avec un commentaire (@), ou obtenir les sources/mods binutils du code source et construire binutils de cette façon. La source de code tend à diriger gnu (support de la commande thumb2 par exemple) ou peut-être backports de nouvelles fonctionnalités, donc je suppose que ces attrubutes de llvm seront présentes dans la ligne principale binutils avant longtemps. Je n'ai subi aucun effet néfaste en coupant les attributs eabi_attributes du code compilé llvm.
Voici la sortie llvm pour la même fonction ci-dessus, apparemment c'est le llc que j'ai modifié pour commenter les attributs eabi_attributes.
.syntax unified
@ .eabi_attribute 20, 1
@ .eabi_attribute 21, 1
@ .eabi_attribute 23, 3
@ .eabi_attribute 24, 1
@ .eabi_attribute 25, 1
@ .eabi_attribute 44, 1
.file "bob.bc"
.text
.globl one
.align 2
.type one,%function
one: @ @one
@ BB#0: @ %entry
add r0, r0, #1
bx lr
.Ltmp0:
.size one, .Ltmp0-one
Le format de fichier elfe est bien documenté et très facile à analyser si vous voulez vraiment voir ce que les directives spécifiques elf (le cas échéant) sont en train de faire. Beaucoup de ces directives doivent aider l'éditeur de liens plus que tout. .thumb_func, .text, .data par exemple.
J'ai ajouté une prime à la question dans l'espoir d'obtenir des réponses plus élaborées, en particulier en ce qui concerne les directives .type et .size. – Oystein
Cela devrait être divisé en une question par directive. Conseil: comprendre le format ELF, puis faire des exemples minimaux avec et sans chaque directive, compiler et «lire -a» sur eux. –