• Aucun résultat trouvé

: programmation en assembleur

Dans le document Architecture des ordinateurs (Page 93-164)

L’IBM 360

Axe 2 : programmation en assembleur

Programmation

103 / 210

Langages bas niveau

Un langage de programmationbas niveauest un langage qui dépend fortement de la structure matérielle de la machine.

Cette caractéristique offre des avantages et des inconvénients divers.

P.ex., elle permet

I d’avoir un bon contrôle desressources matérielles; I d’avoir un contrôle très fin sur lamémoire;

I souvent, de produire du code dont l’exécution est trèsrapide. En revanche, elle ne permet pas

I d’utiliser des techniques de programmation abstraites ; I de programmer rapidement et facilement.

Langage machine

Lelangage machineest un langage compris directement par un processeur donné en vue d’une exécution.

C’est unlangage binaire: ses seules lettres sont les bits0et1.

Chaque modèle de processeur possède son propre langage machine. Étant donnés deux modèles de processeursx1etx2, on dit quex1est

compatibleavecx2si toute instruction formulée pourx2peut être comprise et exécutée parx1.

Dans la plupart des langages machine, une instruction commence par un opcode, une suite de bits qui porte la nature de l’instruction. Celui-ci est suivi des suites de bits codant lesopérandesde l’instruction.

P.ex., la suite

0110101000010101

est une instruction dont le opcode est01101010et l’opérande est 00010101. Elle ordonne de placer la valeur(21)dixen tête de la pile.

107 / 210

Langages d’assemblage

Unlangage d’assemblage(ou assembleur) est un langage qui se trouve à mi-distance entre le programmeur et la machine en terme de facilité d’accès.

En effet, d’un côté, la machine peut convertir presque immédiatement un programme en assembleur vers du langage machine. De l’autre,

l’assembleur est un langage assez facile à manipuler pour un humain.

Les opcodes sont codés via desmnémoniques, mots-clés bien plus manipulables pour le programmeur que les suites binaires associées.

Du fait qu’un langage d’assemblage est spécifiquement dédié à un processeur donné, il existe presque autant de langages d’assemblage qu’il y a de modèles de processeurs.

Langages d’assemblage et assembleurs

L’assemblageest l’action d’un programme nomméassembleurqui consiste à traduire un programme en assembleur vers du langage machine.

Ledésassemblage, réalisé par undésassembleur, est l’opération inverse.

Elle permet de retrouver, à partir d’un programme en langage machine, un programme en assembleur qui lui correspond.

Programmeur Programme

en assembleur

Écriture

Langage machine

Assemblage Désassemblage

Ordinateur

Exécution

109 / 210

L’assembleur NASM

Pour des raisons pédagogiques, nous choisissons de travailler sur une architecturex86en 32 bits. C’est une architecture dont le modèle de processeur est compatible avec le modèle Intel 8086.

Nous utiliserons l’assembleur NASM(Netwide Assembler).

Pour programmer, il faudra disposer : 1. d’un ordinateur (moderne) ;

2. d’un système Linux en 32 bits (réel ou virtuel) ou 64 bits ; 3. d’un éditeur de textes ;

4. du programmenasm(assembleur) ; 5. du programmeld(lieur) ougcc; 6. du programmegdb(débogueur).

Généralités

Unprogramme assembleurest un fichier texte d’extension.asm. Il est constitué de plusieurs parties dont le rôle est

1. d’invoquer desdirectives;

2. de définir desdonnées initialisées;

3. de réserver de la mémoire pour desdonnées non initialisées; 4. de contenir une suiteinstructions.

Nous allons étudier chacune de ces parties.

Avant cela, nous avons besoin de nous familiariser avec trois ingrédients de base dans la programmation assembleur : lesvaleurs, lesregistreset la mémoire.

111 / 210

Exprimer des valeurs

Il y a plusieurs manières d’exprimer des valeurs en assembleur.

On peut exprimer desentiers(représentés par leurs suites de bits obtenues en repr. complément à deux) :

I directement en base dix, p.ex.,0, 10020,-91;

I en hexadécimal, avec le préfixe0x, p.ex.,0xA109C,-0x98; I en binaire, avec le préfixe0b, p.ex.,0b001,0b11101. On peut exprimer descaractères(en repr. ASCII) :

I directement, p.ex.,'a','9'; I par leur code ASCII, p.ex.,10,120.

On peut exprimer deschaînes de caractères(comme suites de carac.) : I directement, p.ex.,'abbaa', 0;

I caractère par caractère, p.ex.,'a', 'a', 46, 36, 0.

Le code ASCII du marqueur de fin de chaîne est0(à ne pas oublier).

Registres et sous-registres

Unregistreest un emplacement de 32 bits.

On peut le considérer comme unevariable globale.

Il y a quatreregistres de travail:eax,ebx,ecxetedx. Il sont subdivisés ensous-registresselon le schéma suivant :

0

31 15

0 7

8 15

e*x*x

*l

*h

P.ex.,bhdésigne le 2eoctet deebxetcxdésigne les deux 1ersoctets deecx. Il est possible d’écrire / lire dans chacun de ces (sous-)registres.

Attention: toute modification d’un sous-registre entraîne une modification du registre tout entier (et réciproquement).

114 / 210

Registres de diverses sortes

Il existe d’autres registres. Parmi ceux-ci, il y a

I lepointeur d’instructioneip, contenant l’adresse de la prochaine instruction à exécuter ;

I lepointeur de tête de pileesp, contenant l’adresse de la tête de la pile ;

I lepointeur de pileebp, utilisé pour contenir l’adresse d’une donnée de la pile dans les fonctions ;

I leregistre de drapeauxflags, utilisé pour contenir des

informations sur le résultat d’une opération qui vient d’être réalisée.

Attention: ce ne sont pas des registres de travail, leur rôle est fixé. Même s’il est possible pour certains d’y écrire / lire explicitement, il faut essayer, pour la plupart, de le faire le moins possible.

L’opération mov — définition

L’instruction

mov REG, VAL

permet derecopierla valeurVALdans le (sous-)registreREG. P.ex., voici les effets de quelques instructions :

I mov eax, 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 eax= 0

I mov ebx, 0xFFFFFFFF

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ebx= 1

I mov eax, 0b101

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1

eax=

I mov al, 5 Le symbole*dénote une valeur non modifiée.

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

*

* 0 0 0 0 0 01 0 01

eax=

116 / 210

L’opération mov — respect des tailles

Il est important, pour que l’instructionmov REG, VALsoit correcte, que la taille en octets de la valeurVALsoit la même que celle du (sous-)registre REG.

P.ex., les instructions suivantesne sont pas correctes:

I mov al, 0xA5A5

Le ss-registrealoccupe 1 octet alors que la valeur0xA5A5en occupe 2.

I mov ax, eax

Le ss-registreaxoccupe 2 octets alors que la valeur contenue danseaxen occupe 4.

I mov eax, ax

Le ss-registreeaxoccupe 4 octets alors que la valeur contenue dansaxen occupe que 2.

En revanche, les instructions suivantessont correctes:

I mov al, 0xA5 I mov ax, 0xF

Le ss-registreaxoccupe 2 octets alors que la valeur0xFn’en occupe que 1. Néanmoins, cette valeur est étendue sur 2 octets sans perte d’information en0x000F.

Opérations sur les registres — arithmétique

Opérationsarithmétiques: I add REG, VAL

incrémente le (sous-)registreREGde la valeurVAL; I sub REG, VAL

décrémente le (sous-)registreREGde la valeurVAL; I mul VAL

multiplie la valeur contenue danseaxetVALet place le résultat dans edx:eax(c.-à-d. la suite de64bits dont les bits deedxsont ceux de poids forts et ceux deeaxceux de poids faibles);

I div VAL

place le quotient de la division deedx:eaxpar la valeurVALdanseax et le reste dansedx.

P.ex., mov eax, 20 add eax, 51 add eax, eax

; eax = 20

; eax = 71

; eax = 142

118 / 210

Opérations sur les registres — logique

Opérationslogiques: I not REG

place dans le (sous-)registreREGla valeur obtenue en réalisant lenon bit à bit de sa valeur ;

I and REG, VAL

place dans le (sous-)registreREGla valeur duetlogique bit à bit entre les suites contenues dansREGetVAL;

I or REG, VAL

place dans le (sous-)registreREGla valeur duoulogique bit à bit entre les suites contenues dansREGetVAL;

I xor REG, VAL

place dans le (sous-)registreREGla valeur duou exclusiflogique bit à bit entre les suites contenues dansREGetVAL.

Opérations sur les registres — bit à bit

Opérationsbit à bit;

I shl REG, NB

décale les bits du (sous-)registreREGà gauche deNBplaces et complète à droite par des0;

I shr REG, NB

décale les bits du (sous-)registreREGà droite deNBplaces et complète à gauche par des0;

I rol REG, NB

réalise une rotation des bits du (sous-)registreREGà gauche deNB places ;

I ror REG, NB

réalise une rotation des bits du (sous-)registreREGà droite deNB places.

120 / 210

Mémoire

Les registres n’offrent pas assez de mémoire pour construire des programmes élaborés. C’est pour cette raison que l’on utilise lamémoire.

La mémoire est segmentée en plusieurs parties :

I lazone statiquequi contient le code et les données statiques ; I letas, de taille variable au fil de

l’exécution ;

I lapile, de taille variable au fil de l’exécution.

Il y a d’autres zones (non repr. ici).

Zone statique

Tas

. . .

Pile Autre

0x00000000

0xBFFFFFFF 0xFFFFFFFF

Enmode protégé, chaque programme en exécution possède son propre environnement de mémoire. Les adresses y sont relatives et non absolues.

De cette manière, un programme en exécution ne peut empiéter sur la mémoire d’un autre.

La lecture / écriture en mémoire suit la conventionlittle-endian.

Lecture en mémoire

L’instruction

mov REG, [ADR]

place dans le (sous-)registreREGun, deux ou quatre octets en fonction de la taille deREG,lusà partir de l’adresseADRdans la mémoire.

En supposant quexsoit une adresse accessible en mémoire, les parties rouges sont celles qui sont lues et placées dans le (sous-)registre opérande de l’instruction :

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov eax, [x]

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov ax, [x]

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov ah, [x]

ou

mov al, [x]

122 / 210

Lecture en mémoire — exemple

Observons l’effet des instructions avec la mémoire dans l’état suivant :

1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 x

x + 1 x + 2 x + 3

mov eax, 0 mov al, [x]

mov ah, [x + 1]

mov ax, [x]

mov eax, [x]

mov ah, [x + 2]

mov ax, [x + 2]

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 eax= 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 0 0 0 0 0 0 1

eax=

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 1

eax=

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1

eax=

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

eax= 1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 1 1 0 0 0 0 1 1

eax=

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 11 10 01 00 01 00 11 10 1 1 0 0 0 0 1 1 eax=

Écriture en mémoire

L’instruction

mov DT [ADR], VAL

écrit dans la mémoireà partir de l’adresseADRla valeurVAL.

Le champDTest un descripteur de taille qui permet de préciser la taille de VALen octet selon la table suivante :

Descripteur de taille Taille (en octets)

byte 1

word 2

dword 4

En supposant quexsoit une adresse accessible en mémoire etvalune valeur, les parties rouges de la mémoire sont celles qui sont modifiées :

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov dword [x], val

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov word [x], val

* * * * * * * *

* * * * * * * *

* * * * * * * *

* * * * * * * *

x x + 1 x + 2 x + 3

mov byte [x], val

124 / 210

Écriture en mémoire — tailles

Le champvalpeut être un (sous-)registre. Dans ce cas, il n’est pas nécessaire de préciser le descripteur de taille (le nombre d’octets écrits en mémoire dépend de la taille du (sous-)registre).

P.ex., les instructions suivantesne sont pas correctes(ici,xest une adresse accessible en mémoire) :

I mov byte [x], eax

Le registreeaxoccupe 4 octets, ce qui est contradictoire avec le descripteur byte(1 octet).

I mov word [x], bl

Le sous-registrebloccupe 1 octet, ce qui est contradictoire avec le descripteurword(2 octets).

I mov byte [x], 0b010010001

La donnée à écrire tient sur au moins 2 octets (9 bits), ce qui est contradictoire avec le descripteurbyte(1 octet).

I mov [x], -125

La taille de la donnée à écrire n’est pas connue.

Écriture en mémoire — tailles

En revanche, les instructions suivantessont correctes: I mov [x], eax

Le registreeaxoccupe implicitement 4 octets.

I mov dword [x], eax

Ceci est correct, bien que pléonastique.

I mov word [x], 0b010010001

La donnée à écrire est vue sur 16 bits, en ajoutant des0à gauche.

I mov dword [x], 0b010010001

La donnée à écrire est vue sur 32 bits, en ajoutant des0à gauche.

I mov word [x], -125

La donnée à écrire est vue sur 2 octets, en ajoutant des1à gauche car elle est négative.

126 / 210

Écriture en mémoire — exemple

Observons l’effet des instructions avec la mémoire dans l’état suivant :

1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 x

x + 1 x + 2 x + 3

mov eax, 0xAA11BB50 mov [x], ah

mov [x], ax mov [x], eax mov byte [x + 1], 0 mov dword [x], 0x5

1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 x

x+1 x+2 x+3

1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 x

x+1 x+2 x+3

0 1 0 1 0 0 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 1 0 x

x+1 x+2 x+3 0 1 0 1 0 0 0 0

1 0 1 1 1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 0 1 0 1 0 x

x+1 x+2 x+3

0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 1 0 x

x+1 x+2 x+3

0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x

x+1 x+2 x+3

Section de données initialisées

Lasection.dataest la partie (facultative) du programme qui regroupe des définitions de données pointées par des adresses.

Elle commence parsection .data. Ondéfinit une donnéepar

ID: DT VAL

oùIDest un identificateur (appeléétiquette),VALune valeur etDTun descripteur de taille parmi les suivants :

Descripteur de taille Taille (en octets)

db 1

dw 2

dd 4

dq 8

Ceci place en mémoire à l’adresseIDla valeurVAL, dont la taille est spécifiée parDT.

La valeur de l’adresseIDest attribuée par le système.

128 / 210

Section de données initialisées — exemples

Quelques exemples de définitions de données initialisées : I entier: dw 55

Créé à l’adresseentierun entier sur 2 octets, initialisé à(55)dix. I x: dd 0xFFE05

Créé à l’adressexun entier sur 4 octets, initialisé à(000FFE05)hex. I y: db 0b11001100

Créé à l’adresseyun entier sur 1 octet initialisé à(11001100)deux. I c: db 'a'

Créé à l’adressecun entier sur 1 octet dont la valeur est le code ASCII du caractère'a'.

I chaine: db 'Test', 0

Créé à partir de l’adressechaineune suite de 5 octets contenant

successivement les codes ASCII des lettres'T','e','s','t'et du marqueur de fin de chaîne.

De plus, à l’adressechaine + 2figure le code ASCII du caractère's'.

Section de données initialisées — définitions multiples

On peutdéfinir plusieurs donnéesde manière concise par ID: times NB DT VAL

oùIDest un identificateur,VALune valeur,DTun descripteur de taille et NBune valeur positive.

Ceci place en mémoire, à partir de l’adresseID,NBoccurrences de la valeur VAL, dont la taille est spécifiée parDT.

P.ex.,

I suite: times 85 dd 5

Créé à partir de l’adressesuiteune suite de85×4octets, où chaque double mot est initialisé à la valeur(5)dix.

L’adresse du 1erdouble mot estsuite.

L’adresse du 7edouble mot estsuite + (6 * 4). I chaine: times 9 db 'a'

Créé à partir de l’adressechaineune suite de9octets tous initialisés par le code ASCII du caractère'a'.

L’adresse du 3eoctet estchaine + 2.

130 / 210

Section de données non initialisées

Lasection.bssest la partie (facultative) du programme qui regroupe des déclarations de données non initialisées pointées par des adresses.

Elle commence parsection .bss.

Ondéclare une donnée non initialiséepar ID: DT NB

oùIDest un identificateur,NBune valeur positive etDTun descripteur de taille parmi les suivants :

Descripteur de taille Taille (en octets)

resb 1

resw 2

resd 4

resq 8

Ceci réserve une zone de mémoire commençant à l’adresseIDet pouvant accueillirNBdonnées dont la taille est spécifiée parDT.

Section de données non initialisées — exemples

P.ex., l’instruction x: resw 120

réserve, à partir de l’adressex, une suite de120×2octets non initialisés.

L’adresse de laiedonnée à partir dexestx + ((i - 1) * 2). Pour écrire la valeur(0xEF01)hexen 4eposition, on utilise l’instruction mov word [x + (3 * 2)], 0xEF01

Pour lire la valeur située en 7eposition à partir dex, on utilise les instructions

mov eax, 0

mov ax, [x + (6 * 2)]

Attention: il ne faut jamais rien supposer sur la valeur initiale d’une donnée non initialisée.

132 / 210

Section d’instructions

Lasection .textest la partie du programme qui regroupe les instructions.

Elle commence parsection .text.

Pour définir le point d’entrée du programme, il faut définir uneétiquette de codeet faire en sorte de la rendre visible depuis l’extérieur.

Pour cela, on écrit section .text global main

main:

INSTR

oùINSTRdénote la suite des instructions du programme. Ici,mainest une étiquette et sa valeur est l’adresse de la 1reinstruction constituantINSTR. La ligneglobal mainsert à rendre l’étiquettemainvisible pour l’édition des liens.

Interruptions — généralités

L’exécution d’un programme se fait instruction par instruction. Dès qu’une instruction est traitée, le processeur s’occupe de la suivante.

Cependant, certaines instructions ont besoin d’interrompre l’exécution pour être menées à bien. Parmi celles-ci, nous avons p.ex.,

I l’écriture de texte sur la sortie standard ; I la lecture d’une donnée sur la sortie standard ; I l’écriture d’une donnée sur le disque ;

I la gestion de la souris ;

I la communication via le réseau ;

I la sollicitation de l’unité graphique ou sonore.

Dans ce but, il existe des instruction particulières appeléesinterruptions.

134 / 210

Interruptions — instruction

L’instruction

int 0x80

permet d’appeler une interruptiondont le traitement est délégué au système (Linux).

La tâche à réaliser est spécifiée par un code lu depuis le registreeax. Voici les principaux :

Code Rôle

1 Arrêt et fin de l’exécution 3 Lecture sur l’entrée standard 4 Écriture sur la sortie standard

Les autres registres de travailebx,ecxetedxjouent le rôle d’arguments à la tâche en question.

Attention: le traitement d’une interruption peut modifier le contenu des registres. Il faut sauvegarder leur valeur dans la mémoire si besoin est.

Interruptions — exemples

Pourstopperl’exécution d’un programme, on utilise mov ebx, 0

mov eax, 1 int 0x80

Le registreebxcontient la valeur de retour de l’exécution.

Pourafficher un caractèresur la sortie standard, on utilise mov ebx, 1

mov ecx, x mov edx, 1 mov eax, 4 int 0x80

La valeur deebxspécifie que l’on écrit sur la sortie standard. Le registre ecxcontient l’adressexdu caractère à afficher et la valeur deedxsignifie qu’il y a un unique caractère à afficher.

136 / 210

Interruptions — exemples

Pourlire un caractèresur l’entrée standard, on utilise mov ebx, 1

mov ecx, x mov edx, 1 mov eax, 3 int 0x80

La valeur deebxspécifie que l’on lit sur l’entrée standard. Le registreecx contient l’adressexà laquelle le code ASCII du caractère lu sera enregistré et la valeur deedxsignifie qu’il y a un unique caractère à lire.

Il est bien entendu possible, pour les interruptions commandant l’écriture et l’affichage de caractères, de placer d’autres valeurs dansedxpour pouvoir écrire / lire plus de caractères.

Directives

Unedirectiveest un élément d’un programme qui n’est pas traduit en langage machine mais qui sert à informer l’assembleur, entre autre, de

I la définition d’une constante ; I l’inclusion d’un fichier.

Pourdéfinir une constante, on se sert de

%define NOM VAL

Ceci fait en sorte que, dans le programme, le symboleNOMest remplacé par le symboleVAL.

Pourinclure un fichier(assembleur.asmou en-tête.inc), on se sert de

%include CHEM

Ceci fait en sorte que le fichier de chemin relatifCHEMsoit inclus dans le programme. Il est ainsi possible d’utiliser son code dans le programme appelant.

138 / 210

Assemblage

Pourassemblerun programmePRGM.asm, on utilise la commande nasm -f elf32 PRGM.asm

Ceci créé unfichier objetnomméPRGM.o.

On obtient un exécutable par l’édition des liens, en utilisant la commande

ld -o PRGM -e main PRGM.o Ceci créé unexécutablenomméPRGM.

L’option-e mainspécifie que le point d’entrée du programme est l’instruction à l’adressemain.

Astuce: sur un système 64 bits, on ajoute pour l’édition des liens l’option -melf_i386, ce qui donne donc la commande

ld -o PRGM -melf_i386 -e main PRGM.o.

Exemple complet de programme

; Def. de donnees section .data chaine_1:

db 'Caractere ? ',0 chaine_2:

db 'Suivant : ',0

; Decl. de donnees section .bss car: resb 1

; Instructions section .text global main main:

; Aff. chaine_1 mov ebx, 1 mov ecx, chaine_1 mov edx, 13 mov eax, 4 int 0x80

; Lect. car.

mov ebx, 1 mov ecx, car mov edx, 1 mov eax, 3 int 0x80

; Incr. car.

mov eax, [car]

add eax, 1 mov [car], al

; Aff. chaine_2 mov ebx, 1 mov ecx, chaine_2 mov edx, 11 mov eax, 4 int 0x80

; Aff. car.

mov ebx, 1 mov ecx, car mov edx, 1 mov eax, 4 int 0x80

; Sortie mov ebx, 0 mov eax, 1 int 0x80

Ce programme lit un caractère sur l’entrée standard et affiche le caractère suivant dans la table ASCII.

140 / 210

Étiquettes d’instruction

Lesinstructionsd’un programme sont des données comme des autres.

Elles ont donc uneadresse.

Tout comme pour les données, il est possible de disposer desétiquettes dans un programme, dont les valeurs sont des adresses d’instructions.

Ceci se fait par

ETIQ: INSTR

oùETIQest le nom de l’étiquette etINSTRune instruction.

mov eax, 0

instr_2: mov ebx, 1 add eax, ebx

P.ex., ici l’étiquetteinstr_2pointe vers l’instruction

mov ebx, 1.

Remarque: nous avons déjà rencontré l’étiquettemain. Il s’agit d’une étiquette d’instruction. Sa valeur est l’adresse de la 1reinstruction du programme.

Pointeur d’instruction et exécution

À chaque instant de l’exécution d’un programme, le registreeip, appelé pointeur d’instruction, contient l’adresse de la prochaine instructionà exécuter.

L’exécution d’un programme s’organise en l’algorithme suivant : 1. répéter, tant que l’exécution n’est pas interrompue :

1.1 charger l’instructionId’adresseeip; 1.2 mettre à joureip;

1.3 traiter l’instructionI.

Par défaut, après le traitement d’une instruction (en tout cas de celles que nous avons vues pour le moment),eipest mis à jour de sorte à contenir l’adresse de l’instruction suivante en mémoire.

Il est impossible d’intervenir directement sur la valeur deeip.

143 / 210

Sauts inconditionnels

Ainsi, par défaut, l’exécution d’un programme se fait instruction par instruction, dans l’ordre dans lequel elles sont écrites.

Néanmoins, il est possible de rompre cette ligne d’exécution en réalisant dessauts. Ils consistent, étant donné un point de départ, à poursuivre l’exécution du programme vers un point cible.

Pour cela, on se sert de l’instruction jmp ETIQ

oùETIQest une étiquette d’instruction. Cette instructionsauteà l’endroit du code pointé parETIQ.

Elle agit enmodifiantde manière adéquatele pointeur d’instruction eip.

Dans le document Architecture des ordinateurs (Page 93-164)

Documents relatifs