Langage assembleur
Procédures et programmation structurée
Pour pouvoir utiliser les procédures en assembleur, nous utiliserons
CALL maProcedure
maProcedure PROC
..
RET
maProcedure ENDP
Langage assembleur – 1ère – PBT
Remarque
Il est clair que ceci est un raccourci !
Nous vous donnons ici uniquement la base afin de pouvoir utiliser les procédures dans vos projets de laboratoires. Les explications plus détaillées suivent dans le cours.
La pile du 80×86
• Une PILE est une structure de données permettant de mémoriser des informations.
• LIFO versus FIFO
– LIFO (Last In First Out) Peut être simulée par une pile d ’assiettes; on empile et on désempile une assiette.
– FIFO (First In First Out) Peut être simulée par une file d ’attente au guichet. « Premier arrivé, premier servi » !
Remarque
La notion de structure de données sera pleinement développée dans d ’autres cours. Ce qu’il faut savoir c’est que, lorsque l ’on veut écrire un programme, il faut s ’attacher à deux choses:
– La structure des données.
– L ’algorithme permettant de traiter ces données.
Tout l ’art (!) de la programmation consiste à regrouper ces deux points. La structuration des données sert, quant à elle, à faire le lien entre les données abstraites d ’un problème et leur représentation « binaire ».
L ’objet de ce cours n ’est pas de traiter des piles, files et autres types abstraits, sachez seulement que le type abstrait pile permet notamment l’écriture de programmes récurcifs.
• Le 80×86 possède une pile LIFO
– SS:SP sont les registres de segment (SS) et d ’offset (SP) permettant d ’accéder aux éléments de la pile.
– .STACK est la directive permettant de fixer la taille de la pile.
– PUSH op et POP op sont les instructions permettant d ’empiler et désempiler un opérande.
Directive .STACK et adresse de la pile
Cette directive précise la taille de la pile: .STACK 100h, réserve une pile de 100h=256d bytes.
La pile est initialisée par le compilateur. Le système fournit donc l ’adresse SS:SP qui est l ’adresse du dernier élément empilé.
• SS est une valeur attribuée par le SE lorsqu’il charge le programme en mémoire.
• SP contient, lors de l’initialisation, la taille de la pile (100h par exemple). Les éléments sont donc empilés « à l ’envers » sur la pile.
Lorsque j ’empile un premier élément d ’un word, SP=0FEh.
(Je décrémente de 2 le pointeur de pile1)
A l ’inverse, lorsque je désempile un word, j ’incrémente le pointeur de pile de deux.
____________________
1 Pointeur de pile = Stack Pointeur = SP
Instruction PUSH
• Syntaxe : PUSH op
• But : empile op. Place le contenu de op sur la pile.
op doit être au WORD ou DWORD
• Opérande : op peut-être :
– Registre : PUSH AX
PUSH EBX
– Mémoire : PUSH word ptr [BX+SI]
– Flags : PUSHF – PUSHFD (386)
– Tout (286) : PUSHA – PUSHAD
Remarque
• L ’opérande doit être au minium un word. Je peux donc, si je défini une pile de 256 bytes empiler 128 mots … ou 54 doubles ou …
• PUSHa
L ’instruction PUSHa (all) empile les registres : AX, BX, CX, DX ainsi que les registres SP, BP, SI, et DI.
Dans le cas de l ’instruction PUSHad, ce sont les registres étendus correspondants qui sont empilés.
• Lorsqu’une instruction (ou une caractéristique) est disponible à partir d ’un processeur particulier, il faut le signaler au compilateur à l ’aide de la directive appropriée; .286, .386 ou .486.
Instruction POP
• Syntaxe : POP op
• But : dépile op. Place le contenu du sommet de la pile dans op.
• Opérande : op peut-être :
– Registre : POP AX
POP EBX
– Mémoire : POP word ptr [BX+SI]
– Flags : POPF – POPFD (386)
– Tout (286) : POPA – POPAD
PUSH CS est autorisé … mais pas POP CS … normal !
Exemples
• PUSH BX
• PUSH word ptr[DI]
• POP EAX
• La pile du 80×86 est de type LIFO. Quel est le résultat des opérations suivantes ?
PUSH AX
PUSH BX
POP AX
POP BX
Les contenus des registres AX et BX sont échangés, ceci est équivalent à :
MOV CX,AX
MOV AX,BX
MOV BX,CX
dans le premier cas, je fais l’économie d ’un registre.
Complément tableaux
Vecteur – Tableau à une dimension • Déclaration
v1 DB a,b,c,d,e,f
v2 DB 10 DUP (?)
• Exemples d ’utilisation
MOV AL,v1[0] AL <- a
MOV BX,offset v1
MOV AL,[BX+2] AL <- c
MOV SI,2
MOV AL,[BX+SI-1] AL <- b
Utilisation
Lorsque l ’on travaille en mode graphique, les vecteurs sont utilisés, par exemple, pour stocker des coordonnées de points. Exemple; supposons que l ’on veuille dessiner 6 carrés de coté 20 pixels à l ’écran (en mode vidéo 12h) aux positions (0,0), (0,20),(0,40),(20,0),(20,20) et (20,40). Si l ’on suppose l ’existence d ’une procédure carré dessinant un carré de coté 20 à l ’écran à la position DX,DL, on peut écrire le morceau de code suivant :
.data
COTE EQU 20
NOMBRE EQU 6
positions DB 0,0,0,20,0,40,20,0,20,20,20,40
…
.code
…
MOV SI,0
repeter:
MOV DX,word ptr positions[SI]
CALL carre
ADD SI,2
frepeter:
CMP SI,2*NOMBRE
JB repeter
…
Tableau à deux dimensions
• Pour représenter un tableau de taille nxm, je réserve n*m bytes (ou word ..).
N EQU 12
M EQU 32
tableau DB N*M DUP (?)
• J ’accède à l ’élément (i,j) :
MOV SI,i
MOV DI,j
MOV AL,tableau[SI*M+DI]
Procédures
Vue minimaliste
Le 80×86 permet la gestion des procédures …
dans une vue minimaliste, cela se résume en deux instructions :
CALL label
RET
Langage assembleur – 1ère – PBT
Rappel
En logique de programmation, une approche top down d ’un problème demande de modulariser l ’algorithme. On aura par exemple :
ACTION
instructions
maFonction() ; appel de la fonction
instructions
maFonction() ; appel de la fonction
instructions
FIN ACTION
; définition de la fonction maFonction MODULE maFonction ()
instructions
FIN MODULE
L ’instruction CALL label
Cette instruction est un branchement à l ’adresse marquée par label.
Traitement de l ’instruction :
– PUSH CS:IP, l ’adresse de l ’instruction suivante est placée sur la pile.
– CS:IP reçoit l’adresse marquée par label.
L ’instruction exécutée après le ‘call’ est celle en position label. (saut)
Exemple
Je place dans l ’exemple des numéros de lignes pour faciliter l ’explication.
Cet exemple ne contient que la partie du code qui nous intéresse.
(1) ; Exemple de « procédure » servant à l ’affichage d ’une
(2) ; chaîne de caractères
(3) MOV DX,offset texte1
(4) CALL affiche
(5) MOV DX,offset texte2
(6) CALL affiche
(7) ; ——– Epilogue ———-
(8) MOV AX,4C00h
(9) INT 21h
(10) affiche:
(11) MOV AH,09h
(12) INT 21h
(13) RET
18
L ’instruction RET
Cette instruction permet le retour à l ’instruction suivant l ’instruction CALL.
Traitement de l ’instruction :
– POP CS:IP, l ’adresse de l ’instruction suivant le CALL est récupérée et placée dans CS:IP. L ’instruction exécutée après le RET est donc celle qui suivait le CALL label.
LASEx04.asm
« Exécution » de l ’exemple précédent
Ligne 3 :
Ligne 4 : CS:IP est placé sur la pile
CS:IP reçoit la valeur du label affiche,
il s ’ensuit un saut au label
Ligne 11 : Exécution de la routine jusqu’à la ligne13
Ligne 13: RET : Récupère dans CS:IP le sommet de la pile,
il s ’ensuit un saut à l ’instruction suivant l ’appel …
Ligne 5:
Ligne 6 : CS:IP est placé sur la pile
CS:IP reçoit la valeur du label affiche,
il s ’ensuit un saut au label
Ligne 11 : Exécution de la routine jusqu’à la ligne13
Ligne 13: RET : Récupère dans CS:IP le sommet de la pile,
il s ’ensuit un saut à l ’instruction suivant l ’appel …
Ligne 8 :
Ligne 9 : Fin du programme
Partage de la pile
• Le 80×86 ne possède qu’une seule pile, attention donc aux conflits entre les instructions PUSH-POP et CALL label – RET.
• Conséquences
– Dans une procédure, autant de PUSH que de POP.
– Le nombre d ’appels de procédures imbriqués est limité par la directive .STACK
• Un « PUSH » sans « POP » dans une procédure …
MOV DX,100
CALL procedure
…
procedure:
PUSH DX
MOV DX,SI
RET
Lors de la rencontre avec l ’instruction RET, IP reçoit la valeur 100 (le sommet de la pile) qui n ’est pas l ’adresse de retour de la procédure … erreur.
• La directive .stack 100h.
S ’il y a x niveaux d ’appel d ’une procédure, cela entraîne x sauvegardes d ’adresse de retour sur la pile. Il faudra veiller à choisir une pile assez grande en cas d ’appels récurcifs d ’une procédure
Vue plus complète …
• Tasm fournit deux pseudo-instructions, permettant de gérer proprement les procédures.
PROC et ENDP
• Avantages
– Ecrire proprement les procédures
– Permet les labels locaux
– Permet de définir un point d ’entrée dans le programme, pseudo-instruction END
Exemples
• La procédure suivante sera appelée par l ’instruction CALL procedure1
procedure1 PROC
PUSHa
… Corps de la procédure …
POPa
RET
procedure1 ENDP
• Définition d ’un point d ’entrée. Dans l ’extrait de code suivant;
main PROC
…
main ENDP
principale PROC
…
principale ENDP
END principale
Ce code commencera par la procédure « principale » avant la procédure « main » grâce à la pseudo-instruction END.
Les commentaires sont absents dans cet exemple … ils viendront plus tard.
• Techniques de programmation et exemples
• Procédures et programmation structurée (1)
• La pile du 80×86
• Compléments sur les tableaux
• Procédures et programmation structurée (2)
– Passage de paramètres par valeur
– Passage de paramètres par adresse
– Variables globales / variables locales
• Récursivité
• Compléments sur les interruptions
• Segmentation mémoire
– Segments logiques
– Directives de segmentation simplifiées
– Directives de segmentation standard
• Le co-processeur mathématique, le 80×87
• Macros
• Les chaînes de caractères
• Manipulation de bits