You are on page 1of 42

1

Le cours ASM propose un aperu de deux langages d'assemblage: x86 et ARM, avec
un accent particulier sur ce dernier. En effet, plus rcent que l'assembleur x86,
l'assembleur ARM joue un rle prpondrant puisqu'il est largement rpandu non
seulement dans les systmes embarqus (comme les smartphones ou tablettes PC),
mais tend aussi se rpandre dans les desktops et serveurs.
Ce chapitre introduit les spcificits des processeurs implmentant les jeux
d'instructions compatibles avec ces deux langages d'assemblage, et donne
galement une brve introduction au langage assembleur.

Les familles des processeurs de type x86 ont une architecture CISC avec des
instructions de taille variable pouvant aller de 1 17 bytes. Elles sont bties sur des
microarchitectures de type x86 avec un souci permanent de prserver une
compatibilit ascendante: ainsi, les gnrations successives de processeurs
admettent plusieurs modes de fonctionnement, qui diffrent en particulier du point
de vue de l'accs la mmoire.
L'architecture fortement pipeline des processeurs x86 (pouvant aller jusqu' plus de
30 tages de pipeline) permet plusieurs instructions d'tre excutes en parallle;
ce type d'architecture est galement nomme superscalaire. Bien entendu,
aujourd'hui, tous les processeurs de type x86 (32/64 bits) sont multicoeurs.
Une particularit intressante au niveau des instructions est la technologie SIMD
(Simple Instruction Multiple Data). C'est une technique largement utilis dans les
processeurs & microcontrleurs permettant d'appliquer des oprations
(arithmtiques) sur un vecteur de donnes, et cela durant le mme cycle d'excution
de l'instruction (donc en parallle).
L'unit matrielle de gestion mmoire (Memory Management Unit) sur x86 est trs
complexe: elle permet de faire de la segmentation (premires gnrations de
processeur x86) et de la pagination. Pour assurer la compatibilit, la traduction
d'une adresse virtuelle sur x86 passe obligatoirement par une traduction de
l'adresse virtuelle vers une adresse linaire (via les segments), puis de l'adresse
linaire vers l'adresse physique.

Un processeur x86 peut grer plusieurs sources d'interruptions: le contrleur


primaire d'interruption sur les dernires versions peut grer jusqu' 256 vecteurs;
ces vecteurs sont utiliss pour des interruptions de type synchrones (interruption
logicielle) ou de type asynchrone (interruption matrielle) ou IRQ (Interrupt
Request). A cela s'ajoute un (voire plusieurs) contrleur d'interruption externe
comme le contrleur "I/O APIC" qui occupe une ligne du LAPIC, et peut luimme
grer 224 sources supplmentaires: il s'agit dans ce cas d'IRQs lies aux
priphriques externes.
Dans une architecture multicoeur, chaque cur dispose de son contrleur LAPIC et
un contrleur matre sera responsable de dispatcher l'interruption sur un cur
disponible (cas gnral pour une architecture de type SMP Symmetric
MultiProcessing), chaque cur pouvant traiter indpendamment tout type
d'interruption externe (la routine de service associe est implante en mmoire et
tous les curs ont accs cette mme mmoire).

Le tableau cidessus rsume l'volution de la technologie Intel au fil des ans. On


remarquera l'apparition de caractristiques importantes comme la prsence d'un
coprocesseur MMX (instructions multimdia, principalement de type SIMD), le
support des 64 bits, les extensions PAE (possibilit d'adresser plus de 4 Go de
mmoire physique), les jeux d'instructions (SSE, SSE2, L3, 3DNow!, etc.) ainsi que la
technologie hyperthreading permettant l'excution parallle de plusieurs threads.

Au dbut des annes 2000, Intel a volu fortement sur le plan marketing en
renommant les familles de processeurs (Athlon, Opteron, Intel Core 2, etc.), ainsi que
les noms de leurs microarchitectures (non montrs dans ce tableau). Des exemples
de microarchitectures sont Pentium Pro, P6, Nehalem, Sandy Bridge, Haswell,
Skylake, Larrabee, Itanium, etc.).
L'volution de ces technologies s'est accompagn d'une concurrence froce,
notamment avec la prsence de la firme AMD, principal rival d'Intel. AMD a
dvelopp ses propres familles de microprocesseurs (rputes nettement moins
cher qu'Intel), tout en implmentant des microarchitectures x86. Les autres
concurrents sont le coren Samsung, l'amricain Texas Instruments, le japonais
Toshiba et la socit francoitalienne STMicroelectronics.

Les processeurs de type ARM sont principalement utiliss dans le contexte des
systmes embarqus au sens large. Le processeur, de type RISC, est beaucoup plus
"simple" qu'un processeur CISC. En revanche, il existe une multitude de contrleurs
intgr au sein mme du composant lectronique (chipset). Les instructions sont en
principe de taille fixe (soit 16 ou 32 bits). La plupart des instructions s'excutent en
un seul cycle d'horloge.
Il est frquent aujourd'hui d'avoir plusieurs coprocesseurs arithmtiques offrant des
instructions de type SIMD, ainsi qu'un DSP (Digital Signal Processing) afin d'offrir une
puissance de calcul leve tout en maintenant une consommation relativement
basse.
Il n'y a pas de segmentation mmoire comme avec un processeur x86. Seule la
pagination est supporte par la MMU. En revanche, il est possible de mapper des
zones mmoires de tailles diffrentes.

La gestion des interruptions sur un processeur ARM est assez diffrente que sur un
processeur x86. Il n'y a en fait que deux lignes physiques qui sont relies du
contrleur d'interruption vers le cur de processeur, savoir les lignes IRQ et FIQ
(pour Fast IRQ, celleci tant par ailleurs peu utilise). Il n'y a donc que deux vecteurs
d'interruption associs aux interruptions matrielles (avec bien entendu d'autres
vecteurs pour les interruptions logicielles/exceptions).
Au niveau de la gestion des IRQs, une architecture multicoeur base sur ARM est
relativement similaire une architecture x86: un contrleur primaire (appel aussi
distributeur) est responsable de dispatcher les interruptions aux contrleurs locaux
chaque cur.

L'volution des processeurs ARM est dcrite cidessus. On remarque des


caractristiques propre ce genre de composant, savoir un mode Thumb pour des
instructions 16 bits, un coprocesseur Jazelle normalement capable d'excuter
directement du bytecode Java (peu voire pas document, donc quasiment pas
utilis!), un DSP, un mcanisme matriel de protection mmoire (MPU) en plus de la
MMU, etc.

Les familles Cortex constituent une des familles de processeur ARM les plus en
vogue aujourd'hui. Elles se dclinent en fonction des types d'application (tempsrel,
multimdia, scurit, etc.).
Les dernires versions de Cortex (CortexA15 notamment) sont multicoeurs (jusqu'
4 curs) et supportent la virtualisation, du point de vue de l'architecture matrielle
et du jeu d'instructions. Les performances de ces processeurs (> 2 Hz) se
rapprochent de plus en plus des processeurs x86 tout en consommant moins
d'nergie et en ayant une architecture volutive moins lourde qu'un x86. Ils
constituent donc une concurrence srieuse Intel, pour les serveurs notamment.

10

Les processeurs x86 offrent 3 modes de base: real mode, protected mode et vm86
mode.
Le mode rel (premier mode) n'offre aucune protection et tait utilis dans les
premires gnrations de processeur, alors que la mmoire ne pouvait dpasser 1
Mo, du fait que seule 20 lignes d'adresse taient prsentes (220 = 1 Mo). Les
registres de segment, comme nous le verrons plus tard, tant implments sur 16
bits, une adresse mmoire tait compose d'un numro de segment, puis d'un
offset cod dans un autre registre de 16 bits. Le numro de segment correspond
alors aux bits de poids fort de l'adresse, et le dplacement ne pouvait tre cod que
sur 4 bits (on remarque la possibilit d'avoir un chevauchement (overlap) des
segments).
Le mode protg change considrablement la manire d'utiliser les registres de
segment: ils ne contiennent plus les bits de poids forts, mais un index dans une table
de segment qui donne une adresse physique contenant le dbut du segment. Le
dplacement cette foisci peut tre cod sur 16 bits si les registres sont de 16 bits,
ou 32 bits avec des registres 32 bits. Avec le mode protg, il est possible d'utiliser
la pagination. Aujourd'hui, seule la pagination est utilise et les segments se
rduisent au nombre d'un seul pour chaque type, avec un offset de 232 (ce qui
permet bien de grer un espace linaire de 4 Go).
Nous nous tendrons pas davantage sur les autres modes.

11

Lorsqu'un processeur x86 dmarre, il est dans le mode "real mode". Trs
rapidement, le code logiciel (en principe du bootloader, voire de l'OS, va implanter
une table de segment avec un minimum d'information afin de passer en mode
protg, et de disposer ainsi d'un adressage adhoc. L'OS pourra par la suite
configurer les tables de page afin d'activer la pagination.
Dans le mode protg, il faut encore pouvoir distinguer entre le mode utilisateur
(user mode) et le mode noyau (kernel mode), afin que tout OS moderne puisse grer
correctement la scurit entre l'espace utilisateur et l'espace noyau.
C'est la notion d'anneau de protection ou ring qui permettra de faire la
diffrence. Gnralement, dans un environnement non virtualis, seul deux rings
sont utiliss: le ring 0 pour le code noyau et le ring 3 pour l'espace utilisateur.
Le bootloader reste en principe dans le ring 0. C'est le systme d'exploitation, lors du
bootstrap, qui commutera en mode utilisateur lorsque toute l'initialisation au niveau
noyau sera termine.

12

Un processeur ARM dispose de 7 modes d'excution: un mode user et 6 modes


privilgis (ou noyau) qui seront utiliss dans des contextes diffrents. Les modes
noyau sont associs chaque interruption de type matrielle ou logicielle pouvant
survenir durant l'excution. De plus, un mode system est utilis au dmarrage du
processeur qui permet la manipulation du registre d'tat servant changer de
mode. En principe, le moniteur ou l'OS utilisera le mode SVC.
L'utilisation de ces modes sera dtaille plus loin dans ce document lors de la
prsentation du modle de registre sur ARM.

13

Dans le cours ASM, nous ne considrerons que les architectures x86 32 bits (et non
64 bits).
Le processeur x86 dispose de 8 registres gnraux dont 4 peuvent tre facilement
accessibles en 8, 16 ou 32 bits, selon le modle de la figure cidessus.
Les registres eax, ebx, ecx, edx sont utiliss librement pour stocker n'importe quelle
valeur et peuvent tre utiliss comme oprandes d'une instruction.
Les registres esi et edi sont plutt utiliss dans le contexte d'adressage par
indexation (index d'une table, d'une zone mmoire, etc.), mais du point de vue du
processeur, ils n'ont pas de signification particulire. C'est le cas aussi pour le
registre bp, qui est gnralement utilis pour prserver une rfrence dans la pile.
En revanche, le registre sp est rserv pour stocker le pointeur de pile et peut tre
altr de manire intrinsque avec certaines instructions, comme nous le verrons
plus tard. De plus les registres bp et sp sont associs au segment utilis pour la pile
(registre SS).
Le registre eip contient l'adresse de la prochaine instruction excuter (ce registre
correspond au Program Counter (PC) d'autres processeurs/microcontrleurs). Il ne
peut tre altr directement, mais est mis jour lors d'instructions de saut.

14

Sur x86, les registres de segment interviennent dans le mcanisme d'adressage


comme il a dj t voqu brivement sur la partie des modes d'excution. Dans le
mode rel, il constitue les bits de poids forts de l'adresse physique, dans le mode
protg, ils identifient le descripteur de segment intervenant dans la traduction de
l'adresse virtuelle vers l'adresse physique. Dans les architectures modernes, ces
registres peuvent rfrer un et un seul segment correspondant l'espace mmoire
complet. L'offset dont la valeur se trouve dans les registres gnraux lors de l'accs
mmoire pourra ainsi aller de 0x0 0xffffffff (232 1).
Un registre trs important est le registre eflags. Celuici contient les flags mis jour
par les instructions arithmtiques/logiques, et contient galement d'autres
informations relative au mode d'excution et aux interruptions.
Le processeur x86 dispose galement d'autres registres systmes dont les plus
importants sont les suivants:
gdtr, ldtr (Global/Local Descriptor Table Register): ces registres sont utiliss pour
stocker l'adresse de la table (globale/locale) des segments
idtr (Interrupt Descriptor Table Register): ce registre contient l'adresse de la table
des vecteurs d'interruption
cr0 (Control Register 0): ce registre contient notamment les bits
d'activation/dsactivation de la pagination (cr3 contient l'adresse de la table de
pages).

15

D'autres registres systme et principalement lis aux coprocesseurs mathmatiques


et multimdias sont prsents cidessous. Il est intressant de remarquer la
variabilit de la taille des registres, ainsi que la prsence de nombreux registres
ddis au traitement des instructions SIMD.
Il est noter galement que pour les registres "traditionnels" du x86, la forme
64bits existe avec le prfixe r (rax, rip, etc.).

16

A l'inverse du x86, le processeur ARM dispose de beaucoup plus de registres


gnraux (sans signification particulire du point de vue du processeur) dont
leur utilisation dpende directement du programmeur qui peut suivre des
conventions ou non. Deux registres cependant ont une signification
particulire: lr et pc, en plus des registres d'tat cpsr et spsr.
Par convention, certains registres ARM prennent des significations
particulires et possdent ds lors des alias connus par le compilateur
d'assemblage et les dsassembleurs. Il s'agit des registres suivants:
r10: SL (Stack Limit)
r11: FP (Frame Pointer)
r12: IP (Scratch Register)
r13: SP (Stack Pointer)
r14: LR (Link Register)
r15: PC (Program Counter)

17

Le registre cpsr correspond au registre eflags du x86. Il contient l'tat des bits lis
l'ALU et comporte des bits systme indiquant le mode d'excution du processeur,
l'tat d'activation des interruptions (IRQ/FIQ), et d'autres bits spcifiques au modle
de processeur et lis au jeu d'instructions; par exemple, le mode Thumb est
dtermin par un bit de ce registre.

Certains registres ARM sont rpliqus physiquement dans les diffrents modes
d'excution. Par exemple, les registres r13 (sp) et r14 (lr) sont physiquement
diffrents d'un mode l'autre. En revanche, il n'existe pas au niveau du langage des
noms diffrents pour les diffrencier. Cela complique quelque peu la
programmation, car lorsque l'on utilise ces registres, il est important de connatre le
mode d'excution du processeur.
La rplication de registres dans les diffrents modes permet de prserver les valeurs
de registre d'un mode l'autre et diminue ainsi l'utilisation de la pile.
Lorsque l'on passe d'un mode l'autre, le programmeur manipule donc des fentres
de registres diffrentes, chaque fentre tant propre au mode d'excution.
Les diffrentes fentres de registres sont examines en dtail dans les pages
suivantes.

19

Le mode user correspond au mode utilis par le systme d'exploitation lorsque le


code s'excute dans l'espace utilisateur. Le registre d'tat est utilis lors d'oprations
arithmtiques par exemple, mais il ne peut tre accd directement; les instructions
manipulant le registre d'tat (cpsr) sont des instructions privilgies.

20

Le mode FIQ est utilis lors d'une interruption matrielle de haute priorit. Le cur
ARM dispose en effet de deux lignes d'interruption matrielle, l'une tant rserve
pour le type d'interruption FIQ (l'utilisation des deux lignes est sous la gestion du
contrleur d'interruption).
Comme le traitement doit tre trs rapide, ce mode dispose de registres r8r14
diffrents. Ces registres (notamment de r8 r12) peuvent donc tre utiliss
directement dans la routine de service lie cette interruption, sans avoir besoin de
prserver les valeurs courantes sur la pile. On vite ainsi des transferts mmoire.

21

Alors que le mode FIQ peut grer des interruptions hautement prioritaire, le mode
IRQ est le mode le plus souvent utilis pour grer des interruptions matrielles; les
temps de latence et de traitement sont suffisamment faibles et conviennent pour la
plupart des applications. Dans ce mode, seuls les registres sp, lr et spsr sont
rpliqus.
A l'instar du mode FIQ, le mode IRQ est utilis dans un contexte d'interruption
matrielle et dispose de sa propre routine de service (un vecteur d'interruption IRQ
ddi). Comme toute routine de service, celleci devra rester aussi petite que
possible afin de ne pas dsactiver les interruptions durant une trop longue priode.
C'est pourquoi, en principe, on cherchera quitter ce mode aussi vite que possible
afin d'viter les problmes de rentrance. C'est le mode SVC qui servira de "mode
principal" pour l'excution de code noyau. Le mode SVC est prsent sur la page
suivante.

22

Le mode SVC est le mode "prfr" pour l'excution de code en mode privilgi
(mode superviseur). Le code peut manipuler toutes les instructions sensibles et
dispose de tous les privilges au niveau de l'espace d'adressage.

23

LemodeUndef estutilislorsd'uneinterruptionlogiciellecorrespondantunchec
l'excutiond'uneinstruction(instructionnonvalide).

24

Le mode Abort est utilis lorsqu'un accs mmoire est invalide. Typiquement, cela
se produit lorsque l'accs une adresse mmoire n'est pas permis, ou qu'il n'existe
aucun mappage entre l'adresse virtuelle et l'adresse physique (faute de page). Ces
aspects sont traits au cours de systme d'exploitation dans le chapitre consacr la
gestion mmoire.

25

Le langage assembleur est compos d'instructions trs proches (parfois


quivalentes) aux instructions machines, cd faisant partie du jeu d'instructions du
processeur/microcontrleur.
Chaque instruction assembleur devra tre convertie en une instruction machine par
un compilateur d'assemblage. Comme tout autre langage, le compilateur gnrera
ainsi un code objet (.o) pour chaque fichier assembleur compil. La diffrence avec
un langage de haut niveau rside bien dans le fait que les instructions utilises dans
le cadre de l'assembleur dpendent totalement du jeu d'instructions machines, donc
du processeur.
Une instruction assembleur peut toutefois driver sur diffrentes instructions
machines, car elle peut tre utilise sous diverses formes, avec des extensions ou
paramtres diffrents. Pour chaque varit d'une instruction, il peut donc y avoir
diffrents codes opratoires (opcodes) correspondants. C'est pourquoi, on nuancera
la notion d'instruction en utilisant la notion de mnmonique qui ce dernier
reprsente une quivalence textuelle d'une instruction machine.

26

Le langage assembleur permet en plus du jeu d'instructions de base d'utiliser des


artifices de langage plus volus qui sont prsents ciaprs.
Les macroinstructions permettent de dfinir de nouvelles instructions bases sur
des instructions de base. Les macroinstructions sont exclusivement des
compositions textuelles, dans le sens qu'elles ne sont pas directement compiles en
tant que telles, mais traites par le prprocesseur qui applique systmatiquement
un remplacement de la macroinstruction par son quivalent code telle que dfini
par le programmeur. Cette notion est tout fait semblable celle utilise avec la
directive #define en langage C par exemple.
Les pseudoinstructions en revanche sont lies au type d'assembleur et sont
traduites par le compilateur cette foisci en instructions de base. La traduction d'une
pseudo en instructions natives est plus complique car elle fait intervenir souvent
des mcanismes d'optimisation et d'adressage complexes.
Les directives de compilation ne sont pas directement lies au type d'assembleur
mais au compilateur. Elles permettent d'informer le compilateur sur la manire de
considrer le texte qui suit la directive, ou de dclarer des constantes, ou des
tiquettes (labels), etc. Les directives ne correspondent donc pas des instructions
machines.

27

En rsum, un langage d'assemblage (ou assembleur) contient toujours des


structures fondamentales, savoir des instructions, des registres, des adresses et
des donnes. En outre, le compilateur comprend des directives de compilation, des
pseudoinstructions et des facilits pour structurer le code un plus haut niveau
d'abstraction telles que les macroinstructions.

28

Un fichier source contenant un programme en langage assembleur ncessite une


structure claire et lisible comme peu prs n'importe quel autre langage. On
s'efforcera de commencer le fichier par la partie dclarative, notamment les
constantes et redfinitions de registre (alias). Puis, les directives de compilation
peuvent tre utiliss des endroits trs diffrents. Les directives commencent
gnralement par un point (.text, .global, etc.) ou un "#" (#include <file>) pour les
directives traites par le prprocesseur.
Un fichier assembleur peut inclure d'autres fichiers l'instar d'un code C.
La dcoupe du programme doit bien faire apparatre les diffrentes fonctions du
programme, mme s'il n'existe pas de notion de fonction en tant que telle en
langage assembleur.
Bien entendu, le code doit tre suffisamment comment. On adoptera les
conventions cidessus pour les commentaires, savoir le signe "@" pour ARM et "#"
pour x86.
Ces considrations sont valables pour l'assembleur x86 et ARM.

29

On veillera ce que les instructions du programme soient correctement indentes; il


faut viter tout prix de varier l'espacement entre les mnmoniques et les
oprandes (paramtres).
On vitera galement l'utilisation de plusieurs mnmoniques sur une mme ligne;
une ligne doit correspondre une instruction (avec ses oprandes/paramtres).
De manire identique une compilation d'un code C, la compilation d'un code
assembleur passe par une phase de preprocessing. Le prprocesseur parcours le
fichier texte et traite ses directives comme l'inclusion de fichier (#include) ou autres
pragmas.
Avec gcc, on peut obtenir les productions intermdiaires (rsultat aprs le pre
processing, traduction dans le langage assembleur natif, etc.) en utilisant l'option
savetemps l'invocation de la compilation. On trouvera ainsi un fichier avec
l'extension .s ( la place de .S) signifiant que cette version de code est le rsultat
intermdiaire du compilateur avant le passage au code objet.

30

Un label dnote un emplacement prcis dans le code. Il faut se reprsenter cette


emplacement au sein de l'espace d'adressage dans lequel le code s'excutera. Ainsi,
grce aux labels, il est possible de spcifier le dbut d'une fonction, ou encore
l'emplacement d'une zone particulire dans laquelle des donnes peuvent tre
dclares, ou encore l'emplacement d'un espace mmoire non initialis.
Le label joue donc un rle central dans la structure du programme (implmentation
d'une boucle par exemple) et permet de rediriger l'excution courante des
emplacements bien prcis. Il peut tre utilis l'intrieur d'une macro.
Un label peut tre compos de chiffres et de lettres. Il est gnralement unique. Si
un label est utilis dans une macro par exemple, et que celleci est instancie
plusieurs fois dans le mme fichier, le label doit tre local et ne peut tre que
numrique. L'utilisation du suffixe b pour backward ou f pour forward permettra au
compilateur de slectionner le label le plus proche en arrire ou en avant.

31

Ds que le symbole de commentaire est rencontr, il est valable jusqu' la fin de la


ligne, cd jusqu'au prochain retour de ligne (CR ou carriage return). Un
commentaire peut commencer en dbut de ligne, ou suivre tout type de code
(instruction, label, etc.).

32

Les directives de compilation (ou directives d'assemblage) sont des lments du


langage d'assembleur qui, d'une part facilitent la programmation d'un code
assembleur, et d'autre part fournissent au prprocesseur et au compilateur des
informations utiles la production d'un code objet et d'un excutable.
A l'instar du langage C, le prprocesseur dispose de directives particulires comme
.include, .equiv, .macro, etc. qui agissent directement sur le texte du programme. Ce
prtraitement gnre alors un nouveau code source intermdiaire qui sera repris
directement par le compilateur.
Les directives d'assemblage lis au compilateur mettent souvent en jeu des calculs
d'adresse parfois complexe, et permettent de grer au mieux l'allocation (statique
ou retarde) de zones de donnes prsentent dans le code objet.
Dans l'univers des compilateurs de la famille GNU, la plupart des directives
d'assemblage sont identiques entre les diffrents langages d'assemblage (x86, ARM,
PowerPC, etc.).

33

Les deux directives cidessus sont lies au prprocesseur : elles auront pour effet
une transformation du code source (en tant que texte) vers le code intermdiaire qui
sera "prsent" au compilateur.
La directive .include permet d'inclure un fichier l'intrieur du fichier en cours de
compilation.
La directive .equiv permet la redfinition de termes l'intrieur du fichier; c'est le
cas par exemple de constantes; chaque occurrence d'une constante sera
systmatiquement remplace par sa valeur correspondante, un niveau textuel.
Dans ce sens, la notion de constante n'a pas de signification particulire du point de
vue du compilateur.

34

La directive .space est trs utile pour la rservation explicite de zone mmoire dans
le code objet, autrement dit dans l'espace d'adressage du code compil. Cette
directive peut tre utilise pour rserver une zone mmoire ddie la pile, par
exemple, ou tout autre type de zone mmoire dans lequel des donnes pourront
prendre place.
Il est intressant de se rendre compte que les adresses croissent en parcourant le
fichier du haut vers le bas. C'est la raison pour laquelle la rfrence stack_high de
l'exemple cidessus indique le sommet de la pile (et non le bas).

35

Les directives de section permettent de dclarer une portion de code ou de donnes


qui suit directement la directive comme faisant partie d'une certaine section.
Dans un programme, diffrents types de section peuvent exister; ces types de
section servent avant tout organiser le code et les donnes d'une manire
structure et scurise : diffrents attributs de protection peuvent en effet tre lis
aux diffrentes zones mmoire correspondantes. Par ailleurs, l'utilisation de sections
permettent au linker et au chargeur de reloger plus aisment le code et les donnes
le cas chant (les adresses sont alors relatives par rapport au dbut d'une section).
Sur un systme d'exploitation, les sections habituelles sont de type code (section
text), donnes (section data pour les variables globales initialises et les constantes,
ou section bss pour les variables globales non initialises), pile (section stack), etc.
Il n'y a pas vraiment de limitations lies au nombre de section ou leur type; il
existe un certain nombre de sections de type prdfini (comme mentionn ci
dessus), mais un programme peut en contenir beaucoup pour des usages trs
diffrents (runtime, debugger, sections dfinies par le dveloppeur, etc.).
Notons que la notion de section apparatra dans le code objet (et l'excutable); le
linker se chargera de rassembler tous les codes objet d'un mme type dans leurs
emplacements respectifs. L'emplacement des sections diverses est souvent dcrite
dans un fichier spcial appel script de linkage.

36

La section bss est gnralement utilise par le compilateur pour dfinir l'ensemble
des variables et donc des zones mmoire correspondantes non initialises. De ce
fait, le code objet stock dans le fichier est rduit car il n'est pas ncessaire de
stocker un ensemble de bytes non initialiss. De plus, la section BSS pourra tre
initialise 0 lors du chargement, aprs avoir allou la mmoire ncessaire.

37

La directive .org informe le compilateur que ce qui suit est placer un certain
offset par rapport au dbut de la section. L'exemple cidessus montre que
l'instruction suivant la directive .org sera place l'adresse 0x18, puisque dans cet
exemple, la section courante (.text) est suppose l'adresse 0x0.
Cette directive peut tre utilise n'importe o dans le fichier, mais ne peut
provoquer une discontinuit de l'espace d'adressage, i.e. il n'est pas possible de
donner un offset qui aboutirait une adresse infrieure la position courante.
Le linker dterminera l'adresse des sections. Un rajustage d'adresse aura lieu
durant l'dition des liens.

38

Les directives .global et .extern sont utilises par le compilateur et le linker. Lorsque
le compilateur traite une rfrence (label) suivant la directive .global, il donne la
possibilit au linker de l'utiliser comme rfrence externe, cd qu'un autre code
objet pourra y rfrer.
Respectivement, lorsqu'une instruction fait rfrence un label qui a t dclar
.extern, le compilateur produira une rfrence symbolique correspondant au nom du
label, rfrence qui sera par la suite rsolue par le linker.

39

La famille de directives cidessus permettent de dclarer des donnes de tout type, y


compris des chanes de caractres.
Les directives principales sont bien entendu .byte, .word et .string
Il faut faire trs attention au fait que les valeurs qui suivent ces directives
correspondent directement aux valeurs qui seront implantes en mmoire, et non
leur taille.

40

La directive .align permet l'alignement de l'adresse qui suit sur un multiple d'un
certain nombre de bytes. Par exemple, un alignement sur un mot de 32 bits conduira
ce que l'adresse soit un multiple de 4 octets, et en d'autres termes, cela signifie
que les 2 derniers bits soient nuls (en effet, on le voit aisment en incrmentant
l'adresse de 4 depuis la valeur 0).
Sur ARM, un tel alignement sur 4 octets est toujours requis au niveau des
instructions; par exemple. le registre pc (r15) est toujours incrment de 4 octets et,
partant de ce constat, les instructions de saut peuvent encoder une adresse sur un
nombre de bits rduit comme nous le verrons plus tard.
Malheureusement, pour des raisons historiques, l'argument de la directive .align n'a
pas la mme signification sur x86 que sur ARM : sur cette dernire, c'est le nombre
de bits 0 que doit comporter la prochaine adresse, alors que sur x86, il s'agit du
nombre d'octets dont l'adresse doit tre un multiple. L'effet est cependant le mme.

41

42

You might also like