Sie sind auf Seite 1von 14

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007

Lassembleur 80x86
1 Lassembleur
1.1 Pourquoi lassembleur ?
Lorsque lon doit lire ou crire un programme en langage machine, il est difficile dutiliser la notation hexadcimale. On crit les programmes laide de symboles comme MOV, ADD, etc. Les concepteurs de processeur, comme Intel, fournissent toujours une documentation avec les codes des instructions de leur processeur, et les symboles correspondant. Il existe un programme, debug , trs utile pour traduire automatiquement les symboles des instructions en code machine. Cependant, debug nest utilisable que pour mettre au point de petits programmes. En effet, le programmeur doit spcifier lui mme les adresses des donnes et des instructions. Soit par exemple le programme suivant, qui multiplie une donne en mmoire par 8 : 0100 MOV BX, [0112] ; charge la donne 0103 MOV AX, 3 0106 SHL BX ; dcale a gauche 0108 DEC AX 0109 JNE 0106 ; recommence 3 fois 010B MOV [0111], BX ; range le rsultat 010E MOV AH, 4C 0110 INT 21H 0112 ; on range ici la donne Nous avons spcifi que la donne tait range ladresse 0111H, et que linstruction de branchement JE allait en 0106H. Si lon dsire modifier lgrement ce programme, par exemple ajouter une instruction avant MOV BX, [0111], il va falloir modifier ces deux adresses. On conoit aisment que ce travail devienne trs difficile si le programme manipule beaucoup de variables. Lutilisation dun assembleur rsout ces problmes. Lassembleur permet en particulier de nommer les variables (un peu comme en langage C) et de reprer par des tiquettes certaines instructions sur lesquelles on va effectuer des branchements. 1.2 De lcriture du programme son excution Lassembleur est un utilitaire qui nest pas interactif, contrairement lutilitaire debug. Le programme que lon dsire traduire en langage machine (on dit assembler) doit tre plac dans un fichier texte (avec lextension .ASM sous DOS). La saisie du programme source au clavier ncessite un programme appel diteur de texte. Lopration dassemblage traduit chaque instruction du programme source en une instruction machine. Le rsultat de lassemblage est enregistr dans un fichier avec lextension .OBJ (fichier objet). Le fichier .OBJ nest pas directement excutable. En effet, il arrive frquemment que lon construise un programme excutable partir de plusieurs fichiers sources. Il faut relier les

Page 1

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 fichiers objets laide dun utilitaire nomm diteur de lien (mme si lon en a quun seul). Lditeur de liens fabrique un fichier excutable, avec lextension .EXE. Le fichier .EXE est directement excutable. Un utilitaire spcial du systme dexploitation (DOS ici), le chargeur est responsable de la lecture du fichier excutable, de son implantation en mmoire principale, puis du lancement du programme. 1.3 Structure du programme source La structure gnrale dun programme assembleur est reprsente figure A Comme tout programme, un programme crit en assembleur comprend des dfinitions de donnes et des instructions, qui scrivent chacune sur une ligne de texte. Les donnes sont dclares par des directives, mots clef spciaux que comprend lassembleur. Les directives qui dclarent des donnes sont regroupes dans le segment de donnes, qui est dlimit par les directives SEGMENT et ENDS. Les instructions sont places dans un autre segment, le segment de code. La directive ASSUME est toujours prsente et sera explique plus loin . La premire instruction du programme (dans le segment dinstruction) doit toujours tre repre par une tiquette. Le fichier doit se terminer par la directive END avec le nom de ltiquette de la premire instruction (ceci permet dindiquer lditeur de liens quelle est la premire instruction excuter lorsque lon lance le programme). Les points-virgules indiquent des commentaires. 1.4 Dclaration de variables On dclare les variables laide de directives. Lassembleur attribue a chaque variable une adresse. Dans le programme, on repre les variables grce leur nom. Les noms des variables (comme les tiquettes) sont composs dune suite de 31 caractres au maximum, commenant obligatoirement par une lettre. Le nom peut comporter des majuscules, des minuscules, des chiffres, plus les caractres @, ? et _.

FIG A Structure dun programme en assembleur (fichier .ASM). Page 2

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007
Lors de la dclaration dune variable, on peut lui affecter une valeur initiale.

Variables de 8 ou 16 bits Les directives DB (Define Byte) et DW (Define Word) permettent de dclarer des variables de respectivement 1 ou 2 octets. Exemple dutilisation : data SEGMENT entree DW 15 ; 2 octets initialises a 15 sortie DW ? ; 2 octets non initialises cle DB ? ; 1 octet non initialise nega DB -1 ; 1 octet initialise a -1 data ENDS Les valeurs initiales peuvent tre donnes en hexadcimal (constante termine par H) ou en binaire (termine par b) : data SEGMENT truc DW 0F0AH ; en hexa masque DB 01110000b ; en binaire data ENDS Les variables sutilisent dans le programme en les dsignant par leur nom. Aprs la dclaration prcdente, on peut crire par exemple : MOV AX, truc AND AL, masque MOV truc, AX Lassembleur se charge de remplacer les noms de variable par les adresses correspondantes. Tableaux Il est aussi possible de dclarer des tableaux, cest dire des suite doctets ou de mots conscutifs. Pour cela, utiliser plusieurs valeurs initiales : data SEGMENT machin db 10, 0FH ; 2 fois 1 octet chose db -2, ALORS data ENDS Remarquez la dclaration de la variable chose : un octet -2 (=FEH), suivi dune suite de caractres. Lassembleur nimpose aucune convention pour la reprsentation des chanes de caractres : cest lutilisateur dajouter si ncessaire un octet nul pour marquer la fin de la chane. Aprs chargement de ce programme, la mmoire aura le contenu suivant :

Page 3

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007

Si lon veut crire un caractre X la place du O de ALORS, on pourra crire : MOV AL, X MOV chose+1, AL Notons que chose+1 est une constante (valeur connue au moment de lassemblage) : linstruction gnre par lassembleur pour MOV chose+1, AL est MOV [adr], AL . Directive dup Lorsque lon veut dclarer un tableau de n cases, toutes initialises la mme valeur, on utilise la directive dup : tab DB 100 dup (15) ; 100 octets valant 15 zzz DW 10 dup (?) ; 10 mots de 16 bits non initialises

2 Segmentation de la mmoire
Nous abordons ici le problme de la segmentation de la mmoire. Nous venons de voir quen assembleur, les donnes taient normalement regroupes dans une zone mmoire nomme segment de donnes, tandis que les instructions taient places dans un segment dinstructions. Ce partage se fonde sur la notion plus gnrale de segment de mmoire, qui est la base du mcanisme de gestion des adresses par les processeurs 80x86. Nous avons vu plus haut prcdemment que les instructions utilisaient normalement des adresses codes sur 16 bits. Nous savons aussi que le registre IP, qui stocke ladresse dune instruction, fait lui aussi 16 bits. Or, avec 16 bits il nest possible dadresser que 216 = 64 Kilo octets. Le bus dadresse du 80486 possde 32 bits. Cette adresse de 32 bits est forme par la juxtaposition dun registre segment (16 bits de poids fort) et dun dplacement (offset, 16 bits de poids faible). Les adresses que nous avons manipules jusquici sont des dplacements. Le schma suivant illustre la formation dune adresse 32 bits partir du segment et du dplacement sur 16 bits :

Page 4

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 On appellera segment de mmoire une zone mmoire adressable avec une valeur fixe du segment (les 16 bits de poids fort). Un segment a donc une taille maximale de 64 Ko. 2.1 Segment de code et de donnes La valeur du segment est stocke dans des registres spciaux de 16 bits. Le registre DS (Data Segment) est utilis pour le segment de donnes, et le registre CS (Code Segment) pour le segment dinstructions. Registre CS Lorsque le processeur lit le code dune instruction, ladresse 32 bits est forme laide du registre segment CS et du registre dplacement IP. La paire de ces deux registres est note CS:IP. Registre DS Le registre DS est utilis pour accder aux donnes manipules par le programme. Ainsi, linstruction MOV AX, [0145] donnera lieu la lecture du mot mmoire dadresse DS:0145H. Initialisation des registres segment Dans ce cours, nous ncrirons pas de programmes utilisant plus de 64 Ko de code et 64 Ko de donnes, ce qui nous permettra de nutiliser quun seul segment de chaque type. Par consquent, la valeur des registres CS et de DS sera fixe une fois pour toute au dbut du programme. Le programmeur en assembleur doit se charger de linitialisation de DS, c'est--dire de lui affecter ladresse du segment de donnes utiliser. Par contre, le registre CS sera automatiquement initialis sur le segment contenant la premire instruction au moment du chargement en mmoire du programme (par le chargeur du systme dexploitation). 2.2 Dclaration dun segment en assembleur Comme nous lavons vu (voir figure A), les directives SEGMENT et ENDS permettent de dfinir les segments de code et de donnes. La directive ASSUME permet dindiquer lassembleur quel est le segment de donnes et celui de code, afin quil gnre des adresses correctes. Enfin, le programme doit commencer, avant toute rfrence au segment de donnes, par initialiser le registre segment DS, de la faon suivante : MOV AX, nom_segment_de_donnees MOV CS, AX (Il serait plus simple de faire MOV CS, nom_segment_de_donnees mais il se trouve que cette instruction nexiste pas.) La figure B donne un exemple complet de programme assembleur.

Page 5

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 3- Adressage indirect Nous introduisons ici un nouveau mode dadressage, ladressage indirect, qui est trs utile par exemple pour traiter des tableaux. Ladressage indirect utilise le registre BX pour stocker ladresse dune donne. En adressage direct, on note ladresse de la donne entre crochets : MOV AX, [130] ; adressage direct De faon similaire, on notera en adressage indirect : MOV AX, [BX] ; adressage direct Ici, BX contient ladressage de la donne. Lavantage de cette technique est que lon peut modifier ladresse en BX, par exemple pour accder la case suivante dun tableau. Avant dutiliser un adressage indirect, il faut charger BX avec ladresse dune donne. Pour cela, on utilise une nouvelle directive de lassembleur, offset.

FIG. B Exemple de programme en assembleur. On calcule la somme de deux variables A et B et on range le rsultat dans la variable nomme Result.

Page 6

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 data SEGMENT truc DW 1996 data ENDS ... MOV BX, offset truc ... Si lon avait employ la forme MOV BX, truc on aurait charg dans BX la valeur stocke en truc (ici 1996), et non son adresse4. 3.1 Exemple : parcours dun tableau Voici un exemple plus complet utilisant ladressage indirect. Ce programme passe un chane de caractres en majuscules. La fin de la chane est repre par un caractre $. On utilise un ET logique pour masquer le bit 5 du caractre et le passer en majuscule (voir le code ASCII). data SEGMENT tab DB Un boeuf Bourguignon, $ data ENDS code SEGMENT ASSUME DS:data, CS:code debut: MOV AX, data MOV DS, AX MOV BX, offset tab ; adresse debut tableau repet: MOV AL, [BX] ; lis 1 caractere AND AL, 11011111b ; force bit 5 a zero MOV [BX], AL ; range le caractere INC BX ; passe au suivant CMP AL, $ ; arrive au $ final ? JNE repet ; sinon recommencer MOV AH, 4CH INT 21H ; Retour au DOS code ENDS END debut

3.2 Spcification de la taille des donnes


Dans certains cas, ladressage indirect est ambigu. Par exemple, si lon crit MOV [BX], 0 ; range 0 a ladresse specifiee par BX lassembleur ne sait pas si linstruction concerne 1, 2 ou 4 octets conscutifs. Afin de lever lambigut, on doit utiliser une directive spcifiant la taille de la donne transfrer : MOV byte ptr [BX], val ; concerne 1 octet MOV word ptr [BX], val ; concerne 1 mot de 2 octets

Page 7

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 4 La pile 4.1 Notion de pile Les piles offrent un nouveau moyen daccder des donnes en mmoire principale, qui est trs utilis pour stocker temporairement des valeurs. Une pile est une zone de mmoire et un pointeur qui conserve ladresse du sommet de la pile. 4.2 Instructions PUSH et POP Deux nouvelles instructions, PUSH et POP, permettent de manipuler la pile. PUSH registre empile le contenu du registre sur la pile. POP registre retire la valeur en haut de la pile et la place dans le registres spcifi. Exemple : transfert de AX vers BX en passant par la pile. PUSH AX ; Pile <- AX POP BX ; BX <- Pile (Note : cet exemple nest pas trs utile, il vaut mieux employer MOV AX, BX.) La pile est souvent utilise pour sauvegarder temporairement le contenu des registres : ; AX et BX contiennent des donnes conserver PUSH AX PUSH BX MOV BX, truc ; on utilise AX ADD AX, BX ; et BX MOV truc, BX POP BX ; recupere lancien BX POP AX ; et lancien AX On voit que la pile peut conserver plusieurs valeurs. La valeur dpile par POP est la dernire valeur empile ; cest pourquoi on parle ici de pile LIFO (Last In First Out, Premier Entr Dernier Sorti). 4.3 Registres SS et SP La pile est stocke dans un segment spar de la mmoire principale. Le processeur possde deux registres ddis la gestion de la pile, SS et SP. Le registre SS (Stack Segment) est un registre segment qui contient ladresse du segment de pile courant (16 bits de poids fort de ladresse). Il est normalement initialis au dbut du programme et reste fix par la suite.

Page 8

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 Le registre SP (Stack Pointer) contient le dplacement du sommet de la pile (16 bits de poids faible de son adresse).

FIG C La pile. Les adresses croissent vers le bas. SP pointe sur le sommet (dernier emplacement occup). La figure C donne une reprsentation schmatique de la pile. Linstruction PUSH effectue les oprations suivantes :

Notons quau dbut (pile vide), SP pointe sous la pile. Linstruction POP effectue le travail inverse :

Si la pile est vide, POP va lire une valeur en dehors de lespace pile, donc imprvisible. 4.4 Dclaration dune pile Pour utiliser une pile en assembleur, il faut dclarer un segment de pile, et y rserver un espace suffisant. Ensuite, il est ncessaire dinitialiser les registres SS et SP pour pointer sous le sommet de la pile. Voici la dclaration dune pile de 200 octets :

Page 9

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007

Noter le mot clef stack aprs la directive SEGMENT, qui indique lassembleur quil sagit dun segment de pile. Afin dinitialiser SP, il faut reprer ladresse du bas de la pile ; cest le rle de la ligne base_pile EQU this word (voir figure D).

FIG. D Une pile vide. Ltiquette base-pile repre la base de la pile, valeur initiale de SP. Aprs les dclarations ci-dessus, on utilisera la squence dinitialisation : ASSUME SS:seg_pile MOV AX, seg_pile MOV SS, AX ; init Stack Segment MOV SP, base_pile ; pile vide Noter que le registre SS sinitialise de faon similaire au registre DS ; par contre, on peut accder directement au registre SP.

5 Procdures
5.1 Notion de procdure
La notion de procdure en assembleur correspond celle de fonction en langage C, ou de sousprogramme dans dautres langages.

Page 10

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007

FIG E Appel dune procdure. La procdure est nomme calcul. Aprs linstruction B, le processeur passe linstruction C de la procdure, puis continue jusqu rencontrer RET et revient linstruction D. Une procdure est une suite dinstructions effectuant une action prcise, qui sont regroupes par commodit et pour viter davoir les crire plusieurs reprises dans le programme. Les procdures sont repres par ladresse de leur premire instruction, laquelle on associe une tiquette en assembleur. Lexcution dune procdure est dclenche par un programme appelant. Une procdure peut elle-mme appeler une autre procdure, et ainsi de suite.

5.2 Instructions CALL et RET


Lappel dune procdure est effectu par linstruction CALL. CALL adresse_debut_procedure Ladresse est sur 16 bits, la procdure est donc dans le mme segment dinstructions. CALL est une nouvelle instruction de branchement inconditionnel. La fin dune procdure est marque par linstruction RET : RET RET ne prend pas dargument ; le processeur passe linstruction place immdiatement aprs le CALL. RET est aussi une instruction de branchement : le registre IP est modifi pour revenir la valeur quil avait avant lappel par CALL. Comment le processeur retrouve-t-il cette valeur ? Le problme est compliqu par le fait que lon peut avoir un nombre quelconque dappels imbriqus, comme sur la figure F Ladresse de retour, utilise par RET, est en fait sauvegarde sur la pile par linstruction CALL. Lorsque le processeur excute linstruction RET, il dpile ladresse sur la pile (comme POP), et la range dans IP.

Page 11

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007

FIG F Plusieurs appels de procdures imbriqus. Linstruction CALL effectue donc les oprations : Empiler la valeur de IP. A ce moment, IP pointe sur linstruction qui suit le CALL. Placer dans IP ladresse de la premire instruction de la procdure (donne en argument). Et linstruction RET : Dpiler une valeur et la ranger dans IP. 5.3 Dclaration dune procdure Lassembleur possde quelques directives facilitant la dclaration de procdures. On dclare une procdure dans le segment dinstruction comme suit :

Le mot clef PROC commence la dfinition dune procdure, near indiquant quil sagit dune procdure situe dans le mme segment dinstructions que le programme appelant. Lappel scrit simplement : CALL Calcul 5.4 Passage de paramtres En gnral, une procdure effectue un traitement sur des donnes (paramtres) qui sont fournies par le programme appelant, et produit un rsultat qui est transmis ce programme. Plusieurs stratgies peuvent tre employes :

Page 12

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 1. Passage par registre : les valeurs des paramtres sont contenues dans des registres du processeur. Cest une mthode simple, mais qui ne convient que si le nombre de paramtres est petit (il y a peu de registres). 2. Passage par la pile : les valeurs des paramtres sont empiles. La procdure lit la pile. Exemple avec passage par registre On va crire une procdure SOMME qui calcule la somme de 2 nombres naturels de 16 bits. Convenons que les entiers sont passs par les registres AX et BX, et que le rsultat sera plac dans le registre AX. La procdure scrit alors trs simplement :

et son appel, par exemple pour ajouter 6 la variable Truc :

Exemple avec passage par la pile Cette technique met en uvre un nouveau registre, BP (Base Pointer), qui permet de lire des valeurs sur la pile sans les dpiler ni modifier SP. Le registre BP permet un mode dadressage indirect spcial, de la forme : MOV AX, [BP+6] cette instruction charge le contenu du mot mmoire dadresse BP+6 dans AX. Ainsi, on lira le sommet de la pile avec : MOV BP, SP ; BP pointe sur le sommet MOV AX, [BP] ; lit sans depiler et le mot suivant avec : MOV AX, [BP+2] ; 2 car 2 octets par mot de pile.

Page 13

Cours Darchitecture des ordinateurs 2me Anne Ingnieur Centre Universitaire de Sada / Dpartement dInformatique 2006-2007 Lappel de la procdure SOMME2 avec passage par la pile est : PUSH 6 PUSH Truc CALL SOMME2 La procdure SOMME2 va lire la pile pour obtenir la valeur des paramtres. Pour cela, il faut bien comprendre quel est le contenu de la pile aprs le CALL :

Le sommet de la pile contient ladresse de retour (ancienne valeur de IP empile par CALL). Chaque lment de la pile occupe deux octets. La procdure SOMME2 scrit donc : SOMME2 PROC near ; AX <- arg1 + arg2 MOV BP, SP ; adresse sommet pile MOV AX, [BP+2] ; charge argument 1 ADD AX, [BP+4] ; ajoute argument 2 RET SOMME2 ENDP La valeur de retour est laisse dans AX. La solution avec passage par la pile parait plus lourde sur cet exemple simple. Cependant, elle est beaucoup plus souple dans le cas gnral que le passage par registre. Il est trs facile par exemple dajouter deux paramtres supplmentaires sur la pile. Une procdure bien crite modifie le moins de registres possible. En gnral, laccumulateur est utilis pour transmettre le rsultat et est donc modifi. Les autres registres utiliss par la procdure seront normalement sauvegards sur la pile. Voici une autre version de SOMME2 qui ne modifie pas la valeur contenue par BP avant lappel :

Noter que les index des arguments (BP+4 et BP+6) sont modifis car on a ajout une valeur au sommet de la pile. Page 14

Das könnte Ihnen auch gefallen