0% ont trouvé ce document utile (0 vote)
244 vues76 pages

Assembleur

Le document décrit les registres et modes d'adressage du microprocesseur 80x86. Il explique les registres généraux, de segments, d'index et la pile. Il détaille les différents modes d'adressage comme direct, indirect et immédiat.

Transféré par

Najwa Aziz
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
244 vues76 pages

Assembleur

Le document décrit les registres et modes d'adressage du microprocesseur 80x86. Il explique les registres généraux, de segments, d'index et la pile. Il détaille les différents modes d'adressage comme direct, indirect et immédiat.

Transféré par

Najwa Aziz
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

MICROPROCESSEURS

ASSEMBLEUR INTEL

Professeur Mohamed HAMLICH


PLAN

INTRODUCTION

LES REGISTRES DU 80X86

LA PILE

MODES D’ADRESSAGE

PROGRAMMATION A L’AIDE DU DEBUG DU DOS

JEU D’INSTRUCTIONS

PROCEDURES

MASM 32
INTRODUCTION
INTRODUCTION:
QUELQUES DÉFINITIONS
LANGAGE MACHINE = ORDRES (EN BINAIRE) COMPRÉHENSIBLES PAR
UN PROCESSEUR DONNÉ

EXÉCUTABLE = SUITE D’INSTRUCTIONS EN LANGAGE MACHINE

LANGAGE ASSEMBLEUR = MNÉMONIQUES ASSOCIÉES AU LANGAGE


MACHINE (JUMP, ADD, MOV…)

ASSEMBLAGE = UTILISATION D’UN LOGICIEL SPÉCIFIQUE (LOGICIEL


D’ASSEMBLAGE OU ASSEMBLEUR) POUR TRANSFORMER UNE SUITE
D’INSTRUCTIONS ÉCRITES EN LANGAGE ASSEMBLEUR EN UN
EXÉCUTABLE
INTRODUCTION:
LES REGISTRES DU 80 X86

MICROPROCESSEUR DES PREMIERS PC ET COMPATIBLES


COMPATIBILITÉ ASCENDANTE : UN PROGRAMME ÉCRIT POUR LE 8086
MARCHE POUR LES PROCESSEURS SUIVANTS

CARACTÉRISTIQUES :
– BUS DE DONNÉES : 16 BITS
– BUS D’ADRESSE : 20 BITS
– REGISTRES : 16 BITS
» ACCUMULATOR (AX)
» BASE (BX)
» COUNTER (CX)
» DATA (DX)
» POINTEUR D’INSTRUCTION (IP)
» REGISTRES SEGMENTS CODE (CS), DATA (DS), EXTRA (ES),
STACK (SS)
» POINTEUR DE PILE (STACK POINTER) (SP), DE BASE (BP)
» INDEX SOURCE (SI), INDEX DESTINATION (DI)
LES REGISTRES DU 80 X86
LES REGISTRES GÉNÉRAUX
ILS SE NOMMENT EAX,EBX,ECX,EDX CE SONT DES REGISTRES DE
32 BITS, QUI SERVENT NOTAMMENT POUR STOCKER LES RÉSULTATS
DES OPÉRATIONS ARITHMÉTIQUES.
LES REGISTRES GÉNÉRAUX
LE REGISTRE EAX
ON PEUT ACCÉDER AUX BITS 0 À 7 DE CE REGISTRE, EN UTILISANT LA
NOTATION AL ( L POUR LOW (BAS EN ANGLAIS)).

PAR EXEMPLE: MOV AL,10H


AURA POUR EFFET DE PLACER LA VALEUR 10H DANS LES BITS 0..7 DU
REGISTRE EAX, LE RESTE DU REGISTRE ÉTANT INCHANGÉ.

POUR ACCÉDER AUX BITS 8 À 15 DE CE REGISTRE, ON DOIT UTILISER


LA NOTATION AH (H POUR HIGH (HAUT EN ANGLAIS))
PAR EXEMPLE:
MOV AH,31H
AURA POUR EFFET DE PLACER LA VALEUR 31H DANS LES BITS 8..15 DU
REGISTRE EAX, LES AUTRES BITS RESTANT INCHANGÉS.
LES REGISTRES GÉNÉRAUX
ON PEUT ACCÉDER AUX BITS 0 À 15 DU REGISTRE EAX, EN UNE SEULE
FOIS, ON DOIT ALORS UTILISER LA NOTATION AX. PAR EXEMPLE:
MOV AX,1234H

ET ENFIN POUR ACCÉDER AU REGISTRE EAX DANS SON INTÉGRALITÉ,


IL SUFFIT DE L'APPELER PAR SON NOM EAX. EXEMPLE :
MOV EAX,12345678H
AURA POUR EFFET DE PLACER LA VALEUR 12345678H DANS LE
REGISTRE EAX.

LES REGISTRES EBX,ECX,ET EDX: SE MANIPULENT EXACTEMENT


COMME LE REGISTRE EAX.
LES REGISTRES DU 80 X86
REGISTRES DE SEGMENTS
LES REGISTRES 16 BITS CS, DS, SS ET ES SONT DES REGISTRES DE
SEGMENT. ILS INDIQUENT QUELLE ZONE DE LA MÉMOIRE EST
UTILISÉE POUR LES DIFFÉRENTES PARTIES D'UN PROGRAMME.

CS POUR SEGMENT DE CODE, REGISTRE PERMETTANT DE FIXER OU DE


CONNAITRE L’ADRESSE DU DÉBUT DES INSTRUCTIONS D’UN
PROGRAMME.

DS POUR SEGMENT DE DONNÉES, CE REGISTRE EST DÉDIÉ À LA


LOCALISATION DE VOS DONNÉES.

SS POUR SEGMENT DE PILE, CE REGISTRE POINTE SUR LA PILE.


COMME JE NE VOUS AI PAS ENCORE EXPLIQUÉ CE QU'EST LA PILE, J'Y
REVIENDRAI PLUS TARD.

ES POUR SEGMENT EXTRA, CE REGISTRE EST UTILE POUR LA


MANIPULATION DE DONNÉES ENTRE PLUSIEURS SEGMENTS EN
PARALLÈLE DES REGISTRES DS, FS ET GS.
• FS et GS pour segment extra, ces registres ont les mêmes
fonctionnalités que le registre DS. Ils sont disponible à partir des
processeurs 80386.
Le Registre d’état:EFLAGS

Indicateurs usuels
CF = Carry Flag ou retenue
PF = Parity Flag ou parité
AF = Auxiliary Carry Flag ou retenue auxiliaire
ZF = Zero Flag ou indicateur de zéro
SF = Sign Flag, ou indicateur de signe
DF = Direction Flag ou indicateur de direction
OF = Overflow Flag ou indicateur de débordement de capacité 13
LE REGISTRE D’ÉTAT:EFLAGS
LES REGISTRES D'INDEX

EDI : 'DESTINATION INDEX', Tire son nom des instructions de copie de


chaîne de caractères, ou il pointait sur la destination. Ces instructions ne
sont quasiment plus utilisées aujourd'hui. On peut s'en servir pour faire
ce que l'on veut à partir du 386.
ESI : 'SOURCE INDEX ' tous comme pour EDI, il servait pour copier des
chaînes de caractères, il pointait sur la source. On peut s'en servir pour
faire ce que l'on veut à partir du 386.
ESP : 'STACK POINTEUR' Il sert à contenir l'offset de l'adresse de la pile,
mieux vaut éviter d'y toucher.
EBP : 'BASE POINTEUR' On en fait, tous comme pour EDI et ESI ce que
l'on veut .
Bien entendu, DI,SI,SP,BP représentent les bits de 0 à 15 de ces registres.
LES REGISTRES D'INDEX

EIP
Il s'agit d'un registre de 32bits (à partir du 386, avant il s'appelait IP et
faisait 16 bits), on ne peut pas y accéder, le microprocesseur s'en sert
pour savoir quelle instruction il doit exécuter, ce registre contient l'offset
par rapport au registre de segment CS, de l'adresse de la prochaine
instruction à exécuter.
LA PILE

• La pile est une zone mémoire, dont le programmeur fixe la taille, et


qui sert à sauvegarder la valeur d'un registre, tous comme à faire
passer des paramètres à un sous programme.

• Pour utiliser la pile nous auront 6 instructions:


PUSH --> pour empiler une valeur
POP --> Pour dépiler une valeur
PUSHA --> Pour empiler le contenu de tous les registres du
microprocesseur (en 16 bits).
POPA --> Pour dépiler le contenu de tous les registres
du microprocesseur (en 16 bits).
LA PILE

PUSHAD --> Pour empiler le contenu de tous les registres du


microprocesseur (en 32 bits).

POPAD --> Pour dépiler le contenu de tous les registres du


microprocesseur (en 32 bits).

La pile dans les microprocesseurs INTEL, est une pile LIFO (Last In
First Out) ce qui signifie que la première valeur dépilée, sera la dernière
que l'on aura empilé.
LA PILE

Exemple:
MOV AX,0010h
MOV BX,1234h
PUSH AX
PUSH BX
POP AX ==> AX contient 1234h
POP BX ==> BX contient 0010h

Cet exemple à permis d'échanger le contenu de deux registres, en se


servant de la pile comme tampon intermédiaire.
LA PILE
LA PILE
Les modes d’adressage

• Modes d’adressages :
– - direct registres
– - direct mémoire
– - indirect via registre de base
– - avec ou sans indexation par registre d’index
• Calcul d’une adresse :
L’accès aux instructions fait implicitement appel à IP basé
par rapport à CS :
Accès aux données
• Lorsqu’un segment logique est ouvert dans un programme source, a
l’assemblage, un compteur lui est alloué.
• Ainsi l’assembleur fait correspondre à chaque étiquette ou nom de
variable une valeur de compteur qui est simplement l’offset du
symbole.
Adressage immédiat
• La donnée est spécifiée immédiatement après l’instruction.
Elle est donc située dans le segment de code.

Quelques exemples :
MOV AX, 0020h
MOV CL, 08h
MOV BX, 0015h

ADD EAX,12345678H

AND AX,1234H
Adressage direct registre

• Les 2 opérandes sont deux registres de même taille


• Quelques exemples : DX=1234h
• MOV AX, DX
AX=1234h et DX=1234h
• MOV CH, AL
• ADD EAX,EBX
EAX=EAX+EBX
• Attention : les données doivent être de même type,
l’instruction suivante est mauvaise :
• MOV CX, BL.
Adressage direct mémoire

• Un opérande est l’adresse d’une case mémoire ou se trouve la


donnée
• MOV AL, [0100h], mettre dans AL le contenu de la case
d’adresse 0100h
• 00fd
• 00fe
• AL=24H 00ff
• MOV [0200h],BL
• BL=26h 0100h
24h
• 0101H
• SUB BL,[0100h]
• BL=BL-[0100h] 0200h
• BL=02h 26h
1) Réalisez les opérations suivantes en assembleur:
A) [0200h]=15h+[0100h]
1ère solution:
B) [0102h]=[0100h] ET [0101h]
• MOV BL,15h
MOV Ah,[0100h]
BL=15h AND Ah,[0101h]
• MOV [0200h],BL MOV [0200h],Ah
[0200h]=15h 2)
• MOV AL,[0100h] MOV AL,[0100h]
MOV BL,[0101h]
AL=[0100h] MOV [0100h],BL
• ADD [0200h],AL MOV [0101h],AL
[0200h]=15h+[0100h]
2ème solution
MOV AL,15h
ADD AL,[0100h] 0100h 45h
MOV [0200h],AL
0101h 89h
B) [0102h]=[0100h] ET [0101h]
2) Permutez les contenus des cases mémoires d’adresses 0100h et 0101h
27
• MOV AL,[0100h]=

• MOV SI,0100h
• MOV AL,[SI]
• Mettre dans AL le contenu de la case mémoire pointée par SI
• J’utilise un pointeur parmi SI, DI, BX et BP

• MOV AX,[0100h]
AX contiendra les contenus de 0100h et de 0101h
MOV EAX, [0100h]
EAX contiendra les cotenus de 0100h,0101h,0102h et de 0103h

28
Adressage indirect mémoire
1. Base ou index
• Lors d’un adressage indirect, la valeur d’affectation n’est
plus le contenu d’un registre, mais la valeur contenu à un
offset égal au contenu du registre.
• SI, DI, BX et BP

Quelques exemples :
MOV AL, [SI] lecture d’un mot
MOV AH, [BX] lecture d’un octet
MOV [DI], AL écriture d’un octet
MOV [DI], [SI] INTERDIT ! ! !
MOV AL,[SI]
MOV [DI],AL
• Les lignes :
• MOV AX, [SI][BX]
• et
• MOV AX, [SI + BX]
• Sont identiques. Cet adressage peut aussi être utilisé pour
écrire en mémoire :
• MOV [DI][BX], CX
• Par contre, la ligne suivante est fausse :
• MOV DX, [SI] [DI]
• Car l’utilisation simultané de deux index est interdite pour
un adressage.
• Il est possible d’utiliser ce mode d’adressage pour la lecture
ou l’écriture :
• MOV AX, [BX] DATA1
• MOV [SI] DATA2, CX
• Il est possible aussi d’ajouter un déplacement
supplémentaire à l’aide du valeur immédiate : MOV AX,
[DI] DATA3(2)
• Ici, on effectue un déplacement supplémentaire de deux
octets.
Mode d’adressage relatif
1) Saut inconditionnel
a) JMP etiq
etiq: MOV AL,BL
ADD AL,25h
JMP etiq
b) CALL fonction fonction: MOV AH,AL
…….RET
MOV AL,CL
ADD [0100H],AL
……. 33
Mode d’adressage relatif
2) Saut conditionnel
a) JE etiq
CMP AL,25h
JE etiq; sauter à etiq si AL egal à 25h sinon continuer
MOV BL,1
JMP fin
etiq: MOV BL,0
fin: END

b) CALL fonction fonction: MOV AH,AL


…….RET
MOV AL,CL
ADD [0100H],AL
……. 34
Mode d’adressage relatif
2) Saut conditionnel
b) JB etiq
CMP AL,25h
JB etiq; sauter à etiq si AL < 25h sinon continuer
MOV BL,1
JMP fin
etiq: MOV BL,0
fin: END

35
Mode d’adressage relatif
2) Saut conditionnel
c) JA etiq
CMP AL,25h
JA etiq; sauter à etiq si AL > 25h sinon continuer
MOV BL,1
JMP fin
etiq: MOV BL,0
fin: END

36
Exercices
1) Comparer les contenus des cases d’adresses 0100h et 0101h et mettre le plus
grand dans la case d’adresse 0200h
MOV AL,[0100h]
MOV [0200h],AL
0100h 25h 0120h
CMP AL,[0101h]
0101h 12h 0121h
JA fin
0102h 56h 0122h
MOV BL,[0101h]
MOV [0200h],BL 0103h 36h 0123h
Fin:END
2) Copiez la zone mémoire d’adresse 0100h à 0110h vers la zone d’adresses 0120h à
0130h
MOV SI,0100h INC SI
MOV DI,0120h INC DI
Etiq: MOV AL,[SI] CMP SI,0110h
MOV [DI],AL JBE etiq
END
37
LE JEU D’INSTRUCTIONS
• Les instructions arithmétiques :
• INSTRUCTION <destination>, <source>

• Le résultat du calcul entre l'opérande source et l'opérande de


destination sera placé dans l'opérande de destination, ceci s'applique
pour la plupart des instructions de ce type.
• Exemple: ADD AX, BX est équivalant à AX = AX + BX.
• AX = 148 (10010100), BX = 69 (01000101)
• ADD AX, BX
• AX =148 + 69 = 217

• SUB AX, BX
• AX =217 - 69 = 148
• ADD modifie les flags Zero, Overflow et Carry suivant le résultat.
SUB modifie les flags Zero et Sign suivant le résultat.
MUL et DIV
• MUL <opérande source> » AX = AX * opérande source
• DIV <opérande source> » AX = AX / opérande source
• MUL et DIV ne s'utilisent qu'avec des nombres non signés, c'est-
à-dire qui ne sont pas négatif (16 bits en non signé: les nombres
vont de 0 à 65535, 8 bits en non signé: les nombres vont de 0 à
255, ...). Le reste de la division est placé dans DX :
IMUL et IDIV
• Ces deux instructions s'apparentent à l'opération MUL et DIV mise à
part qu'elles utilisent des nombres signés, c'est-à-dire qui peuvent être
négatifs (16 bits en signé: les nombres vont de -32768 à 32767, 8 bits
en signé: les nombres vont de -126 à 127, ...). Le reste de la division
est placé dans DX :
NEG
• NEG inverse le signe de l'opérande

• INC
<destination>
•DEC <destination>

AH = 12
INC AX ; AX = 12 + 1 = 13

DEC AX ; AX = 13 - 1 = 12
MOV
• MOV <destination>, <source>
• MOV EAX, [EAX] » Transfère dans EAX la donnée qu'il pointe.
CMP

• L'instruction CMP est identique à SUB mais n'affecte pas le


résultat à l'opérande de destination, elle permet de vérifier si
deux valeurs sont égales dans la plupart des cas, la syntaxe
est la suivante :
• CMP <destination>, <source>
• L'instruction CMP modifie tous les drapeaux; c'est en
analysant les flags que l'on pourra savoir si une expression
est différente d'une autre par exemple :
Evolution des flags ZF et CF avec l'instruction CMP g, d (gauche,
droite); g et d étant non signés :
Instructions de contrôle

• Par défaut, exécution séquentielle des instructions


• Possibilité de sauter à d'autres endroits du programme de 2
façons
• Saut à une adresse du programme
• Saut conditionnel à une adresse du programme
• Pas de structures de contrôle plus évoluées
• Pas de boucles
• Pas de if then else ou de switch
Instructions de contrôle
• Dans le code du programme en assembleur
• Peut placer des labels pour marquer un endroit de la séquence d'instructions
• Instruction de saut : JMP
• JMP label
• Exemple
• MOV AX, [1000h]
• MOV BX, [1004h]
• JMP calcul
• suite:
• MOV [BX],AX
• ..
• calcul:
• ADD AX, BX
• JMP suite
Les sauts conditionnels :
Saut fondés sur l'égalité :
• Saut fondés sur des comparaisons (d'entiers non signés) :

• INSTRUCTION g, d (gauche, droite)



Instructions de contrôle

• On peut avec des sauts conditionnels reproduire des instructions de


contrôle de plus haut niveau
• If ... then ... else
• if (AX = 3)
• then BX = 5 else BX = DX
• CMP AX, 3
• JNE else ; si pas égal, on saute à else
• MOV BX, 5 ; sinon on est dans le then
• JMP endif ; on saute le then pour aller à la fin du if
• else:
• MOV BX, DX
• endif:
Instructions de contrôle

• for (cx=0; cx<5; cx++)


• ax = ax + cx
• MOV AX,0 ; initialisation de AX et CX à 0
• MOV CX,0 ; CX est le compteur de boucle
• for:
• CMP CX, 5 ; compare CX à 5
• JGE endfor ; si CX >= 5, on sort de la boucle
• ADD AX, CX ; fait le calcul
• INC CX ; CX est incrémenté de 1
• JMP for ; on reprend au début de la boucle
• endfor:
• Pour boucle for précédente, peut utiliser une autre instruction
• LOOP label
• Décrémente CX et fait le saut à label si CX > 0
• for (cx=5; cx>0; cx--)
• ax = ax + cx
• MOV AX,0
• MOV CX,5 ; CX est le compteur de boucle
• for:
• ADD AX,CX ; fait le calcul
• LOOP for ; décrémente CX. Si CX > 0 fait
• ; le saut à for
• Exemple avec saut sur drapeau
• ADD AX, BX
• JO erreur
• ...
• erreur:
• MOV AX, 0
• Si débordement (overflow) lors de l'addition de AX et BX,
on saute au label erreur
• Instructions concernant le registre d'état
• LAHF opération : transfère le registre d'état dans AH
• SAHF opération : transfère AH dans le registre d'état
• CLC opération : mise à zéro de l'indicateur de retenue
• STC opération : mise à un de l'indicateur de retenue
• CMC opération : inversion de l'indicateur de retenue
• CLD opération : mise à zéro de l'indicateur de direction.
• Les instructions de traitement de chaînes se feront en incrémentant
les index.
• STD opération : mise à un de l'indicateur de direction.
• Les instructions de traitement de chaînes se feront en décrémentant
les index.
• CLI opération : Interdit la prise en compte des interruptions physiques
• STI opération : Autorise la prise en compte des interruptions
physiques
• Entrées / Sorties
• IN reg,port opération : transfère un octet ou un mot selon
que reg est AL ou AX depuis un contrôleur de périphérique
désigné par son n°. La désignation du contrôleur peut être
une valeur (0 à 255) ou le registre DX (0 à 65535).
• OUT port,reg opération : transfère un octet ou un mot selon
que reg est AL ou AX vers un contrôleur de périphérique
désigné par son n°. La désignation du contrôleur peut être
une valeur (0 à 255) ou le registre DX (0 à 65535).
Traitement de chaînes

• LODSB opération : place dans AL l'octet pointé par DS:SI puis SI est
incrémenté ou décrémenté selon la valeur du bit de direction (voir
CLD/STD).
• LODSW opération : place dans AX le mot de 16 bits pointé par DS:SI
puis SI est augmenté ou diminué de 2 selon la valeur du bit de
direction (voir CLD/STD).
• STOSB opération : place AL dans l'octet pointé par ES:DI puis DI est
incrémenté ou décrémenté selon la valeur du bit de direction (voir
CLD/STD).
• STOSW opération : place AX dans le mot de 16 bits pointé par ES:DI
puis DI est augmenté ou diminué de 2 selon la valeur du bit de
direction (voir CLD/STD).
• MOVSB opération : copie l'octet pointé par DS:SI dans celui pointé
par ES:DI puis, SI et DI sont incrémentés ou décrémentés selon la
valeur du bit de direction (voir CLD/STD).
Traitement de chaînes

• Remarque : Chacune des instructions ci-dessus peut être précédée du


préfixe REP qui repète CX fois l'instruction. Après chaque exécution de
l'instruction, CX est décrémenté et la répétition cesse lorsqu'il est nul.

• Ainsi REP MOVSB copie la zone de CX octets pointée par DS:SI vers la
zone pointée par ES:DI.

• Aprés chaque transfert d'octet, SI et DI sont incrémentés ou


décrémentés selon la valeur du bit de direction.
Traitement de chaînes

• SCASB opération : compare AL à l'octet pointé par ES:DI puis SI est


incrémenté ou décrémenté selon la valeur du bit de direction (voir
CLD/STD).
• SCASW opération : compare AX au mot de 16 bits pointé par ES:DI
puis SI est augmenté ou diminué de 2 selon la valeur du bit de
direction (voir CLD/STD).
• CMPSB opération : compare l'octet pointé par ES:DI à celui pointé par
DS:SI puis, SI et DI sont incrémentés ou décrémentés selon la valeur
du bit de direction (voir CLD/STD).
• CMPSW opération : compare le mot de 16 bits pointé par ES:DI à celui
pointé par DS:SI Puis, SI et DI sont augmentés ou diminués de 2 selon
la valeur du bit de direction (voir CLD/STD).
Traitement de chaînes
• Remarque : Chacune des instructions ci-dessus peut être précédée du
préfixe REPE ou du préfixe REPNE:
• REPE répète l'instruction tant qu'il y a égalité. Après chaque
exécution de l'instruction, CX est décrémenté et la répétition cesse
lorsqu'il est nul ou lorsque la condition d'égalité n'est pas remplie.
• REPNE répète l'instruction tant qu'il n'y a pas égalité. Après chaque
exécution de l'instruction, CX est décrémenté et la répétition cesse
lorsqu'il est nul ou lorsque la condition d'égalité est remplie.
• Ainsi REPE CMPSB compare la zone de CX octets pointée par DS:SI à
la zone pointée par ES:DI.
• Après chaque comparaison d'octet, SI et DI sont incrémentés ou
décrémentés selon la valeur du bit de direction La comparaison
s'arrête lorsque CX est nul (fin de zone atteinte sans rencontrer de
différence) ou dès la première différence rencontrée (DS:SI et ES:DI
pointent sur l'octet qui constitue cette différence)
Procédures
• On peut définir des procédures en assembleur x86
• Pour les paramètres des procédures et la valeur de retour, 2
méthodes
• Utiliser des registres
• Simple
• Mais registres peu nombreux et doit toujours utiliser les mêmes à
chaque appel donc assez contraignant
• Passer par la pile
• On empile les paramètres de la procédure
• On appelle la procédure
• On dépile les paramètres et résultats
• Plus compliqué mais plus général
Gestion de la pile
• Gestion de la pile, 4 opérations
• PUSH : empiler une valeur sur la pile
• POP : dépiler une valeur de la pile
• PUSHA : empiler les 8 registres généraux sur la pile
• POPA : positionne les valeurs des 8 registres à partir des 8 valeurs au
sommet de la pile
• PUSHA et POPA permettent de sauvegarder et restaurer simplement l'état
des registres
• Avant un appel de procédure par exemple
• Egalement des opérations pour dépiler/empiler registre d'état
• Pour lire des éléments de la pile sans les dépiler
• MOV AX, [SP] ; AX prend la première valeur en sommet de pile
• MOV AX, [SP+2] ; AX prend la deuxième valeur en sommet de pile
Procédures
• Déclaration d'une procédure
• nomProc PROC
• ...
• instructions de la procédure
• ...
• RET
• nomProc ENDP
• Appel d'une procédure
• CALL nomProc
• Quand appelle une procédure, le registre IP est empilé sur la pile
pour savoir où revenir
Procédures
• Exemple par registre
• Procédure qui retourne le double de la somme de AX et DX
• calcul PROC
• ADD AX, DX ; addition
• SHL AX, 1 ; décalage gauche = X 2
• RET
• calcul ENDP
• .....
• MOV AX, 10
• MOV DX, 20
• CALL calcul ; après l'appel, AX contient le résultat
• Procédures
• Même exemple avec passage propre par pile
• Propre car les registres restent dans le même état
• calcul PROC
• PUSH BP ; sauvegarde base de la pile
• MOV BP, SP ; nouvelle base de pile = sommet pile
• PUSH AX ; sauvegarde AX
• MOV AX, [BP+4] ; récupère argument 2
• ADD AX, [BP+6] ; addition AX et argument 1
• SHL AX, 1 ; décalage gauche = X 2
• MOV [BP+6],AX ; remplace argument 1 par résultat
• POP AX ; restaure AX
• POP BP ; restaure la base de la pile
• RET
• calcul ENDP
• Procédures
• Appel de la procédure du transparent précédent
• PUSH 10 ; empile l'argument 1
• PUSH 20 ; empile l'argument 2
• CALL calcul
• POP AX ; dépile l'argument 2
• POP AX ; AX contient le résultat
Masm32 et les Api Windows
Premier programme:
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE \masm32\include\windows.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDELIB \masm32\lib\user32.lib

.data
Msg DB "Hello World !",0
TitleMsg DB "MsgBox.asm",0

.code
Main:
push MB_OK ;Bouton Ok.
push OFFSET TitleMsg ;Titre.
push OFFSET Msg ;Message.
push NULL ;hwnd dans ce cas 0.
call MessageBox
push 0h
call ExitProcess
END Main
Masm32 et les Api Windows
Le programme ne fait rien d'autre que terminer le processus, dans
lequel il est, en appelant la fonction particulière de Windows :
"ExitProcess".

1) Type de machine utilisé : ".386"


Permet l'usage du mode 32 bits et l'utilisation du jeu d'instructions du
processeurs 386 et ascendant.

2) Modèle mémoire utilisé : ".model flat, stdcall"


"flat", signifie plat. C'est le modèle mémoire utilisé sous win32
(windows 32 bits).
"stdcall", signifie : appel standard c'est-à-dire la façon dont sont
transmis les paramètres à la fonction. Les paramètres sont transmis de
la droite vers la gauche.
Masm32 et les Api Windows
3) Inclusion : "include C:\masm32\include\kernel32.inc“

"Include" signifie inclusion. Il permet l'usage de la fonction qui est


incluse dans le fichier librairie.
Le fichier "Kernel32.inc" contient les déclarations de toutes les fonctions
comprises dans "Kernel32.lib".
Pour pouvoir utiliser une fonction d'une librairie il faut informer le
compilateur du nom et de ses paramètres.
Ce fichier est donc très important au moment de la compilation.
La fonction utilisée est : "ExitProcess" et se trouve dans la librairie
"Kernel32.lib".
Masm32 et les Api Windows
4) Inclusion de librairie : "includelib C:\masm32\lib\kernel32.lib"
"Includelib" signifie inclusion d'une librairie.
Le fichier "Kernel32.lib" contient le code de la fonction "ExitProcess".
Le compilateur extraira la fonction et la joindra au fichier ".obj" qui en
résultera.

5) Déclaration d'un segment de code : "CODE Segment 'code'"


Tout programme informatique sous Windows nécessite qu'il soit logé
dans une zone mémoire appelée segment.
Un segment de code est l'enveloppe principale du programme.
Cette déclaration permet de signifier au compilateur et au lieur que
nous voulons créer un segment mémoire qui contiendra notre code.
Masm32 et les Api Windows
6) Déclaration d'une fonction : "Main:"
Le code doit-être contenu dans une enveloppe appelée procédure qui
est elle même contenue dans le segment de code. Avec MASM32 une
procédure peut être déclarée de façon basique comme dans ce code.
Le code de la procédure débute à l'adresse représentée ici par "Main:".
Lors du liage Main sera remplacé par une adresse offset. Une adresse
offset est une valeur relative par rapport au début du code.

7)Paramètre de fonction : "push 0"


Cette instruction du jeu d'instructions du microprocesseur, demande au
microprocesseur de mettre sur la pile le paramètre qui suit, c'est-à-dire
la valeur numérique 0.
Si une fonction est appelée et nécessite le passage d'un paramètre il
faudra utiliser l'instruction "push" puis appeler la fonction. La syntaxe
est la même pour tout passage de paramètres à une fonction.
Masm32 et les Api Windows
8) Fonction Windows : "call ExitProcess"
Cette instruction appelle la fonction "ExitProcess" de Windows qui se
trouve dans la librairie "Kernel32.lib".
Elle termine le programme.

9) Fin de fonction "Main" :


Dans l'exemple ci-dessus la fin de la procédure se termine à l'instruction
: "call ExitProcess".

10) Fin de segment de code : "CODE ends"


Idem pour le segment de code.
"ends", signifie : fin de segment.
Masm32 et les Api Windows
Compilation
• Copiez le code puis collez le (il est recommandé de le réécrire afin
d'assimiler plus rapidement) dans un nouveau document au format
texte avec l'extension ".asm".

• Nommez ce fichier par exemple : "Cours1.asm" et enregistrez le dans


le répertoire "C:\Exemple".

• Puis en ligne de commandes tapez :


C:\masm32\bin\ml /c /coff c:\Exemple\Cours1.asm
Masm32 et les Api Windows
Editeur de lien et exécution

• La compilation aura généré le fichier "Cours1.obj" que vous copierez


dans le répertoire "C:\Exemple".

• Ensuite, utilisez le lieur de la façon suivante :


C:\masm32\bin\link /subsystem:console c:\Exemple\Cours1.obj

• Les fichiers "Cours1.obj" et "Cours1.exe" sont générés dans le


répertoire courant. Copiez les dans le répertoire "C:\Exemple" si ce
n'est pas le répertoire courant.
Masm32 et les Api Windows
Assemble & Link
• Les étapes de compilation :
– ml /c /coff monfichier.asm
– Link /subsystem:console monfichier.asm
– Link /subsystem:windows monfichier.asm
Masm32 et les Api Windows
2ème Programme
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
Msg db "Hello World!", 0
TitleMsg DB "MsgBox.asm"
.code
start:
lea edx,Msg
mov al,"*"
add edx,6
mov [edx],al
push MB_OK
push OFFSET TitleMsg
push OFFSET Msg
push NULL
call MessageBox
end start

Vous aimerez peut-être aussi