71
Djamal Rebaïne 1 Les piles

Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Embed Size (px)

Citation preview

Page 1: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 1

Les piles

Page 2: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 2

• Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres. Il s'agit d'un moyen d'accéder à des données en les empilant, telle une pile de livre, puis en les dépilant pour les utiliser. Ainsi il est nécessaire de dépiler les valeurs stocker au sommet (les dernières à avoir été stockées) pour pouvoir accéder aux valeurs situées à la base de la pile.

• En réalité il s'agit d'une zone de mémoire et d'un pointeur qui permet de repérer le sommet de la pile. La pile est de type LIFO (Last In First Out), c'est-à-dire que la première valeur empilée sera la dernière sortie (Si vous empilez des livres, il vous faudra les dépiler en commençant par enlever les livres du dessus. Le premier livre empilé sera donc le dernier sorti!).

• Les instructions PUSH et POP Les instructions PUSH et POP sont les instructions qui servent à empiler et dépiler les données.

• PUSH registre met le contenu du registre dans la pile (empilement) • POP registre récupère le contenu de la pile et le stocke dans le

registre (dépilage

Page 3: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 3

Ainsi, l'instruction PUSH BX empile le contenu du registre BX,

et l'instruction

POP AX

récupère le contenu du sommet de la pile et le transfère dans AX.

Page 4: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 4

Utilisation de la pile sur un exemple

• Dans l'exemple suivant, que l'on imaginera au milieu d'un programme, on stocke les valeurs contenues dans AX et BX pour pouvoir utiliser ces deux registres, puis une fois l'opération accomplie on remet les valeurs qu'ils contenaient précédemment...

Page 5: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 5

• PUSH AX

• PUSH BX

• MOV AX, [0140]

• ADD BX, AX

• MOV [0140], BX

• POP BX

• POP AX

Page 6: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 6

• Les registres SS et SP Les registres SS et SP sont deux registres servant à gérer la pile:

• SS (Stack Segment, dont la traduction est segment de pile) est un registre 16 bits contenant l'adresse du segment de pile courant.

• Il doit être initialisé au début du programme

• SP (Stack Pointer, littéralement pointeur de pile) est le déplacement pour atteindre le sommet de la pile (16 bits de poids faible).

Page 7: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 7

• SP pointe vers le sommet, c'est-à-dire sur le dernier bloc occupé de la pile. Lorsque l'on ajoute un élément à la pile, l'adresse contenue dans SP est décrémentée de 2 octets (car un emplacement de la pile fait 16 bits de longueur).

• En effet, lorsque l'on parcourt la pile de la base vers le sommet, les adresse décroissent. Par contre l'instruction POP incrémente de 2 octets (16 bits) la valeur de SP.

Page 8: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 8

• PUSH: SP <- SP - 2

• POP: SP <- SP + 2

• Ainsi, lorsque la pile est vide SP pointe sous la pile (la case mémoire en-dessous de la base de la pile) car il n'y a pas de case occupée. Un POP provoquera alors une erreur...

Page 9: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 9

Déclarer une pile • Pour pouvoir utiliser une pile, il faut la déclarer,

c'est-à-dire réserver un espace mémoire pour son utilisation, puis initialiser les registres avec les valeurs correspondant à la base de la pile, ainsi que son sommet (rappel: situé sous la pile lorsque celle-ci est vide).

• Ainsi pour définir une pile, il s'agit tout d'abord de la déclarer grâce à la directive SEGMENT stack.

Page 10: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 10

Déclaration d'une pile Pour utiliser une pile en assembleur, il faut déclarer un segment de pile, et y

réserver un espace suffisant. Ensuite, il est nécessaire d'initialiser les registres SS et SP pour pointer sous le sommet de la pile. Voici la déclaration d'une pile de 200 octets :

segment_pile SEGMENT stack ; mot clef stack pour pile DW 100 dup (?) ; réserve espace base_pile EQU this word ; etiquette base de la pile segment_pile ENDS

Noter le mot clef ``stack '' après la directive SEGMENT, qui indique à l'assembleur qu'il s'agit d'un segment de pile.

Afin d'initialiser SP, il faut repérer l'adresse du bas de la pile; c'est le rôle de la ligne base_pile EQU this word (voir figure suivante).

En fait l’opérateur this word (ne pas oublier que les éléments d’un pile sont des mots) crée une adresse mémoire qui est le mot suivant et l’assigne à bas_pile. Comme les adresse d’une pile sont dans l’ordre décroissant, cette adresse en dessous de l’adrese du début de la pile.

Page 11: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Autrement dit, la déclaration suivante:

First-byte equ this byte

Word table dw 100 dup(?)

permet d’assigner un nom au premier octet de l’adresse de word-table.

Page 12: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 12

                                                   

Page 13: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 13

• Suite aux déclarations, il faut écrire une séquence d'initialisations:

• ASSUME SS:segment_pile; génère une adresse pour l’emplacement de la ; pile• MOV AX, segment_pile • MOV SS, AX ; initialise le segment de pile • MOV SP, base_pile ; copier l'adresse de la base de la pile dans SP

• Remarquez qu’il n'est pas possible de faire directement MOV SS, segment_pile car cette instruction n'existe pas!

Page 14: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 14

Les procédures-fonctions

La notion de procédure - fonctions En langage assembleur, on appelle procédure un sous-

programme qui permet d'effectuer un ensemble d'instructions par simple appel de la procédure. Cette notion de sous-programme est généralement appelée fonction dans d'autres langages. Les fonctions et les procédure permettent d'exécuter dans plusieurs parties du programme une série d'instruction, cela permet une simplicité du code et donc une taille de programme minimale. D'autre part, une procédure peut faire appel à elle-même, on parle alors de procédure récursive (il ne faut pas oublier de mettre une condition de sortie au risque sinon de ne pas pouvoir arrêter le programme...).

Page 15: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 15

Page 16: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 16

La déclaration d'une procédure Étant donnée qu'une procédure est une suite d'instructions, il

s'agit de regrouper les instructions composant la procédure entre des mots clés. L'ensemble de cette manipulation est appelée déclaration de procédure.

Ces mots clés permettant la déclaration de la procédure sont le

1. une étiquette (qui représente le nom de la fonction) précédant

2. le mot clef PROC marquant le début de la procédure, 3. suivi de near (qui signale que la procédure est située dans

le même segment que le programme appelant) et 4. RET désignant la dernière instruction, 5. et enfin le mot-clé ENDP qui annonce la fin de la procédure.

Ainsi une déclaration de procédure ressemble à ceci:

Page 17: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 17

Etiquette PROC near 

instruction1  

instruction2  

...  

RET 

Etiquette ENDP 

Page 18: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 18

Appel d'une procédure

C'est la directive CALL qui permet l'appel d'une procédure. Elle est suivie soit d'une adresse 16 bits, désignant la position du début de la procédure, ou bien du nom de la procédure (celui de l'étiquette qui précède le mot clé PROC).

Page 19: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 19

Comment l'appel et la fin de la procédure

Lorsqu'on appelle une procédure, la première adresse de la procédure est stockée dans le registre IP (pointeur d’instruction), le processeur traite ensuite toutes les lignes d'instructions jusqu'à tomber sur le mot clé RET, qui va remettre dans le registre IP l'adresse qui y était stocké avant l'appel par PROC.

Cela paraît simple mais le problème provient du fait que les procédures peuvent être imbriqués, c'est-à-dire que de saut en saut, le processeur doit être capable de revenir successivement aux adresses de retour. En fait, à chaque appel de fonction via l'instruction CALL, le processeur empile l'adresse contenue dans le registre IP (il pointe alors sur l'instruction suivant l'instruction CALL) avant de la modifier, à l'appel de l'instruction RET (qui ne prend pas d'arguments) le contenu de la pile est dépilé puis stocké dans le registre IP.

Page 20: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 20

                                                                  

Page 21: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 21

Voici un exemple d’utilisation des procédures aussi simple que possible :

ce programme appelle 12 fois une procédure qui écrit un message à l’écran et rend la main au DOS.

Remarque : Les codes ASCII 10 et 13 représentent respectivement la fin de ligne et le retour chariot. Grâce à eux, on revient à la ligne chaque fois qu’on a écrit le message.

Page 22: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 22

Title les procéduresPile segment stack dw 100 dup (?) Basedepile equ thisword Pile endsdata segement message db ’bonjour, monde!’, 10,13, ‘$’data ends

code segment assume cs:code, ds:code, ss:piledebut: MOV AX, data ; initialise le segment de données MOV DS, AX MOV AX, Pile MOV SS, AX ; initialise le segment de pile MOV SP, basedepile

MOV CX,12 boucle: call ecritmessage ; appel de procédure LOOP boucle ; décrementer CX d’une unité et aller à ; boucle si CX est différent de 0

; terminer le programme ici par le retour au DOS

mov AX, 4C00h INT 21H

Page 23: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 23

ecritmessage proc near ;notre procédure mov ah, 09h move dx,offset message int 21h retecritmessage endp ; fin de la procédure/fonction

code ends ; fin du segment de code end debut ; fin de la porte d’entrée

Page 24: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 24

Le passage de paramètres Une procédure effectue généralement des actions sur des données

qu'on lui fournit, toutefois dans la déclaration de la procédure il n'y a pas de paramètres (dans des langages évolués on place généralement les noms des variables comme paramètres entre des parenthèses, séparés par des virgules). Il existe toutefois deux façons de passer des paramètres à une procédure:

Le passage des paramètres par registre: on stocke les valeurs dans les registres utilisés dans la procédure

Le passage des paramètres par pile: on stocke les valeurs dans la pile avant d'appeler la procédure, puis on lit le contenu de la pile dans la procédure.

Le passage de paramètres par registres C'est une méthode simple pour passer des paramètres: Elle consiste à écrire une procédure en faisant référence à des registres dans les instructions, et de mettre les valeurs que l'on désire dans les registres juste avant l’appel de la fonction...

Page 25: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 25

Le passage des paramètres par registre Cette manière de procéder est très simple à mettre en oeuvre mais

elle est très limité, car on ne peut pas passer autant de paramètres que l'on désire, à cause du nombre limité de registres. On lui préfèrera le passage des paramètres par pile.

Le passage de paramètres par pileCette méthode de passage de paramètres consiste à stocker les

valeurs des paramètres dans la pile avant l'appel de procédure (grâce à l'instruction PUSH), puis de lire le contenu de la pile grâce à un registre spécial (BP: Base pointer) qui permet de lire des valeurs dans la pile sans les dépiler, ni modifier le pointeur de sommet de pile (SP).

Page 26: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 26

L'appel de la procédure se fera comme suit:

PUSH parametre1 ; où parametre1 correspond à une valeur ou une adresse

PUSH parametre2 ; où parametre1 correspond à une valeur ou une adresse

CALL procedure

La procédure commencera par l'instruction suivante:

MOV BP, SP ;permet de faire pointer BP sur le sommet de la pile

Puis pourra contenir des instructions du type:

MOV AX, [BP] ;Stocke la valeur contenue dans le sommet de ;la pile dans AX, sans dépiler MOV BX, [BP+2] ;Stocke la valeur contenue dans le mot suivant de la ;pile dans BX (un mot fait 2 octets), sans dépiler

Page 27: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 27

• On va écrire une procédure ``SOMME'' qui calcule la somme de 2 nombres naturels de 16 bits.

• Convenons que les entiers sont passés par les registres AX et BX, et que le résultat sera placé dans le registre AX.

• La procédure s'écrit alors très simplement :

Exemple avec passage par registre

Page 28: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 28

SOMME PROC near ; AX <- AX + BX ADD AX, BX RET SOMME ENDP

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

MOV AX, 6 MOV BX, Truc CALL SOMME MOV Truc, AX

Page 29: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 29

Exemple avec passage par la pile

Cette technique met en oeuvre un nouveau registre, BP (Base Pointer), qui permet de lire des valeurs sur la pile sans les dépiler ni modifier SP.

Le registre BP permet un mode d'adressage indirect spécial, de la forme :

MOV AX, [BP+6]; cette instruction charge le contenu du mot mémoire d'adresse 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 dépiler et le mot suivant avec : MOV AX, [BP+2] ;2 car 2 octets par mot de pile.

• L'appel de la procédure ``SOMME2'' avec passage par la pile est :

PUSH 6 PUSH Truc CALL SOMME2

Page 30: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 30

; passage de paramètres

push AX push BX push CX push DX call soubroutine ; branchement vers la procédure ; ......... Contineur traitement

soubroutine proc near mov BP,SP ; pointe vers le sommet de pile move AX, [BP+2] ; acquérir dernier paramètre (DX) sans dépiler; pourquoi? move AX, [BP+4] ; acquérir 3ème paramètre (CX) sans dépiler move AX, [BP+6] ; acquérir 2ème paramètre (BX) sans dépiler move AX, [BP+8] ; acquérir premeir paramètre (AX) sans dépiler ........... retsoubroutine ends

Page 31: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 31

Emplacement de sous-programmes

En général, les sous-programmes sont mis à la fin du programme principal. Mais, on peut aussi les mettre dans la partie du segment de code. Seulement,il faudra s’assurer que la première instruction de code exécutée soit celle du programme principal. Pour cela, il suffit juste de mettre un JMP juste avant la déclaration du sous-programme.

Page 32: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 32

Exemple: le calcul de PGCD de plusieurs nombres

TITLE PGCDdeplusieursnombres

SPILE SEGMENT STACK

DW 100 DUP(?)

SPILE ENDS

SDATA SEGMENT

valeurs DB 10,30,40,76,32,52

resultat DB 3 dup(?)

tab_sortie db 7 dup('$')

tab_conv db 7 dup('$')

start dw 0

SDATA ENDS

SCODE SEGMENT

ASSUME CS:SCODE,DS:SDATA

JMP debut

PGCD proc near ; déclaration de la fonction

repet:

MOV AL,CL

MOV AH,0

IDIV CH;

CMP AH,0

JE dfin

MOV CL, CH

MOV CH, AH

JMP repet

dfin:

RET ;le PGCD est dans CH

PGCD ENDP ;fin de la procédure PGCD

Page 33: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 33

DEBUT: mov ax,sdata mov ds,ax mov SI,0; sert d’indice tableau MOV BX, 5; compteur de nombre à manipuler mov CH, valeurs[SI] INC SIrepeter:

CMP BX,0 JE fin mov CL, valeurs[SI] Call PGCD INC SI DEC BX JMP repeterFin: ; le PGCD de tous les nombres est dans CH

Page 34: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 34

xor ax,ax ; tout ce qui suit sert à afficher les chiffres contenus dans le PGCD qui est dans CHmov al,chmov si, offset tab_convmov start, offset tab_conv ;start sert à garder le début du tableau

mov bx,0mov bl,10

division: ; on suppose que la division se fait sur des nombre de 16 bits div bl cmp al,0 je fin_div add ah,48 mov byte ptr[si],ah mov ah,0 inc si jmp divisionfin_div: add ah,48 mov byte ptr[si],ah ; tab_conv contient le nombre converti à l’envers xor bx,bx mov bx, offset tab_sortie xor ax,ax

Page 35: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 35

st_bcl:cmp si,start

jb fin_bclmov ah , byte ptr[si]mov byte ptr[bx] , ah

dec si inc bx jmp st_bclfin_bcl: mov byte ptr[bx],10 inc bx mov byte ptr[bx],13 inc bx mov byte ptr[bx],'$' mov dx,offset tab_sortie mov ah,09h int 21hSortie: MOV AX, 4c00h; Int 21hSCODE ENDS END DEBUT

Page 36: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 36

La récursivité

• Définition:

Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement

Page 37: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 37

Fonctionnement d’une fonctionrécursive

• Création d’une pile pour la sauvegarde entre autres des paramètres d’appels de la procédure et la l’adresse de retour.

Page 38: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 38

Calculer le factoriel de n, noté n!

• Le problème est: Calculer le factoriel d'un nombre entier donné en entrée.

• En entrée: Nous avons n nombre entiers qui sont plus grands ou égaux à 0.

• Sortie: Nous avons un nombre entier qui représente le factoriel de n.

Page 39: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 39

• Fonction principale• entier n nfact• lire n • si (n < 0) alors écrire “entrée négative: ” n• sinon• nfact factoriel(n)• écrire “la factorielle de ” n “est” nfact

• où factoriel satisfait le prototype

• entier factoriel(entier)

Page 40: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 40

Fonction factoriel

int factoriel(entier n) {

si (n < 1) retourner 1retourner n * factoriel(n-1)

}

Page 41: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 41

Comment le faire en assembleur?

On a besoin d’une pile!• En effet, à chaque appel récursif, la valeur du paramètre

n est sauvegardée dans la pile de travail. • Ce processus d’empilement est répété jusqu’à ce que le

paramètre actuel (de l’appel) n atteigne la valeur 0. Cela correspond à la fin de l’exécution de la fonction appelante.

• Ensuite, commence le dépilement, et l’exécution de la prochaine instruction de la fonction appelante est entamée. Ce processus de dépilement est répété jusqu’à ce qu’on atteigne la valeur de départ du paramètre n.

Page 42: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 42

Cela se traduit par le programme assembleur suivantTITLE factoriel PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segment N dw 4 fact dw ?Data endsCode segment assume CS:code, DS:Data, SS:Pile Debut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP mov BX,n; sauvegarde la valeur de n mov AX,BX Push AX call factoriel Fin: pop AX; le résultat calculé par la fonction factoriel est dans AX mov fact, AX mov AX,4c00h int 21h

Page 43: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 43

Factoriel proc near ; en utilisant la pile CMP AX,0 JA DEPILE MOV AX,1 JMP fin

DEPILE: ; dépiler jusqu’à ce n = 0 DEC AX PUSH AX ; factoriel(n-1) CALL FACTORIAL

RetourResultat: POP BX MUL BX fin: ret factoriel endp ; fin de la procédurecode ends end debut ; fin du programme code

Page 44: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 44

Calcul d’une somme par récursivitéTitle sommerecursive; pour totaliser la somme de 1 jusqu’à n.PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segment N dw 12 som dw ?Data endsCode segment assume CS:code, DS:Data, SS:Pile Debut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP mov CX,n; sauvegarde la valeur de n XOR AX,AX CALL sommerecursive Fin: pop AX; le résultat calculé par la fonction factoriel est dans AX mov fact, AX mov AX,4c00h int 21h

Page 45: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 45

sommerecursive proc near ; en utilisant des registres

CMP CX,0

JZ fin

ADD AX,CX

DEC CX

CALL sommerecursive

fin: ret

factoriel endp ; fin de la procédure

code ends

end debut ; fin du programme code

Page 46: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 46

Les nombres de Fibonacci

• Question: Écrire un programme qui calcule le nombre de Fibonacci défini comme suit:

1;0

1 n si ;

10

21

FF

FFF nnn

èmen

Page 47: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 47

TITLE fibonacciSPILE SEGMENT STACK DW 100 DUP(?)SPILE ENDSSDATA SEGMENT n dw 6SDATA ENDSSCODE SEGMENT ASSUME CS:SCODE,DS:SDATA DEBUT: mov ax,sdata mov ds,ax xor ax,ax xor bx,bx mov ax,n call fibo mov dl,al; afficher le résultat add dl,30h mov ah,2 int 21hsortie: MOV AX,4C00H INT 21H

Page 48: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 48

Fibo proc si1: cmp ax, 1 ; comparer ax avec 1 ja els ; si n<= 1, retourner 1 mov ax, 1 ; mettre 1 dans ax retels: dec ax ; décrémenter ax de 1 c'est-à-dire égal à n-1 push ax ; mettre n-1 sur la pile call Fibo ; résultat dans ax pop bx ; rectifier la pile et bx = n-1 dec bx ; bx = n -2 push ax ; sauvegarder ax = Fibonacci(n-1) sur la pile mov ax,bx ; passe le n-1 à ax pour exécuter Fibonacci(n-2) call Fibo ; résultat dans ax = Fibonacci(n-2) pop bx ; bx = Fibonacci(n-1) add ax, bx ; ax = Fibonacci(n-2) + Fibonacci(n-1) retFibo endpSCODE ENDS END DEBUT

Page 49: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 49

Les tours de Hanoï

http://www.multimania.com/fmaire/jeux/hanoi/hanoi.html

http://members.aa.net/~wgf/Hanoi/Hanoi.html

Page 50: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 50

• Description du problème: Montrez comment déplacer n disques de tailles distinctes d'une tige A vers une tige B

• en utilisant comme tampon une tige C. Initialement seule la tige A contient les n disques ordonnés avec le plus petit sur le dessus. On ne doit déplacer qu'un seul disque à la fois. Il est interdit de placer un disque sur un autre plus petit.

• Entrée: Un entier n représentant le nombre de disques.

• Sortie: Une série d'instructions de la forme " déplacer i vers j" indiquant les déplacements nécessaires pour résoudre le problème.

Page 51: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 51

• Fonction principale

entier nlire nhanoi(n,1,2,3)

où hanoi satisfait le prototype

hanoi(entier, entier, entier, entier)

Page 52: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 52

• Supposons qu’on sache comment déplacer les (n-1) derniers disques de la tour 1 vers la tour 2, en utilisant la tour 3.

• déplacer le disque restant de la tour 1 vers la tour 2

• déplacer maintenant les (n-1) disques de la tour 3 vers la tour 2, en s’aidant de la tour 1.

Page 53: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 53

Fonction hanoi

Entête:• hanoi(entier n, entier i, entier j, entier k)• (Affiche les instructions pour déplacer n disques • de la tige i vers la tige k)Corps:• si (n > 0)• {• hanoi(n-1, i, k, j)• écrire "Déplacer i vers k);• hanoi(n-1, j, i, k)• }

Page 54: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 54

#include <iostream.h>

void hanoi (int,int,int,int)

void hanoi(int n,int i,int j,int k){

if (n>0){

hanoi(n-1,i,k,j);

cout <<“déplacer le disque de haut de la tour<<i<<“ à la tour “<<k;

hanoi(n-1,j,k,i);

}

main(){

int n;

cin>>n;

hanoi(n,1,2,3);

}

Page 55: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 55

• Cette fonction est à revoir Tours-de-Hanoi PROC NEAR;

push bpmov eb,spmov ax,[bp+4]add eax,0x4

mov dx,[ax] push dx call atoi

add sp,0x4 push word 0x2 ; INITIALISER LA PILE À dohanoi push word 0x1 ; dohanoi(n, to from, using) push word 0x3 push word ax call dohanoi add sp,16 mov sp,bp pop bp

ret

Page 56: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

dohanoi: push bp mov bp,sp mov ax,[bp+4]

cmp ax,0x0 jle fini dec ax

push [bp+ 12] ; empiler le premier appel récursif push dword [ebp+16]

push dword [ebp+20]push dword eaxcall dohanoi

add esp,16 push dword [ebp+16] ; a disk moved, so print it push dword [ebp+12]

call DeplaceLeadd esp,8mov eax,[ebp+8]dec eaxpush dword [ebp+16] ; empiler le deuxième appel récursif

push dword [ebp+20]push dword [ebp+12]push dword eaxcall dohanoiadd esp,16

Page 57: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 57

fini: mov esp,ebp pop ebp ret

deplaceLe: push ebpmov ebp,esppush dword [ebp+8]push dword [ebp+12]push dword movestrcall printfadd esp,0xcmov esp,ebppop ebpret

Tours-de-Hanoi ENDP

Page 58: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 58

Remarquons qu’il est possible de supprimer carrément l’appel récursif, en le simulant par des appels successifs à la pile, à travers les empilements et les dépilements.

Reprenons le problème de la fonction factoriel.

Page 59: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 59

Cela se traduit par le programme assembleur suivant

TITLE factoriel PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segment N dw 4 fact dw ?Data endsCode segment assume CS:code, DS:Data, SS:Pile Debut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP mov BX,n; sauvegarde la valeur de n mov ax,bx call factoriel Fin: pop AX; le résultat calculé par la fonction factoriel est dans AX mov fact, AX mov AX,4c00h int 21h

Page 60: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 60

factoriel proc near push axContinuer:

CMP AX,1 JLE dépiler; déplier jusqu’à ce n = 1 dec AX push AX JMP continuer

Depiler: POP AX POP CX mul CX Push AX CMP BX,CX Ja depiler ret factoriel endp ; fin de la procédurecode ends end debut ; fin du programme code

Page 61: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 61

Inversion d’une chaine de caractères

• Donnée: S une chaine de caractères

• Question: Afficher S dans le sens inverse

Page 62: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 62

• Fonction principale

• ecrire “introdroduire la chaîne: ”

• inverser

Page 63: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 63

• La fonction inverser fonctionne comme suit:

Tant que le caractère lu n’est pas le point, continuer la lecture;

Arrivé au point, l’affichage commence.

Page 64: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 64

Entête: inverser Corps:

lire car; si car <> `.` inverser; afficher car;

Page 65: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 65

TITLE inverser

affiche macro chaine ; mov dx,offset chaine ; mov ah, 09h ; int 21hendm PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segmentChaine db ‘introduire votre chaine’, 10,13, ‘$’Data endsCode segment assume CS:code, DS:Data, SS:PileDebut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP Affich chaine call inverserlFin: mov AX,4c00h int 21h

Page 66: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 66

inverser Proc near Continuer: mov ah,1 ;lecture d’un cacactère int 21h CMP AL,’.’ JNE dépiler; dépiler jusqu’à ce AL = ‘.’ CBW ; convertir le caractère en un mot ; ou alors faire mov AH,0 push AX JMP continuer

Depiler: POP AX mov AH,2 int 21 JMP depilerret inverser; fin de la procédure

code ends; fin du programme principal end debut

Page 67: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 67

• Rechercher l’élément C dans un tableau trié dans l’ordre croissant.

…………… …..

milieuL u

AC?

Page 68: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 68

void recherche(C,L,u:entier; trouve:booleen)

{ trouve = faux;

si (u <= L) et (non trouve)

{ milieu = (u - L + 1) div 2;

si A[milieu] = C

trouve = vrai;

sinon si A[milieu] > C

recherche(C,L,milieu-1);

sinon recherche(C,milieu+1,u);

}

}

Page 69: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 69

TITLE dichotomique

PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segmenttableau db 100 dup(?)Valeur db ?Data endsCode segment assume CS:code, DS:Data, SS:PileDebut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP

mov dx,offset tableau

mov ah,0ah; lecture à partir du clavier d’une chaîne de caractères

; qui se termine dès qu’on tape le retour chariot (touche entrée)

int 21h

Page 70: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 70

mov SI, offset tableau ADD SI,2 ; adresse du premier élément mov BX, tableau[si+1]; nombre d’éléments dec BX ; indice du dernier élément ADD BX, SI; adresse du dernier élément mov ah,1; introduire la valeur à rechercher int 21h mov Valeur,AL XOR AX,AX call dichotoFin: mov AX,4c00h int 21hCode ends end debut

Page 71: Djamal Rebaïne1 Les piles. Djamal Rebaïne2 Utilité d'une pile Une pile est une zone de mémoire dans laquelle on peut stocker temporairement des registres

Djamal Rebaïne 71

Dichoto proc nearContinuer: CMP BX, SI JL fin ; continuer jusqu’à il n’y ait plus d’élément à rechercher mov AX, BX SUB AX, SI INC AX DIV 2 MOV DI,AL; mettre la valeur du milieu du tableau dans DI CMP tableau[DI], Valeur JE trouve; la valeur est trouvée JG Gauche; la valeur ne se trouve pas dans la partie droite MOV SI, DI INC SI JMP continuertrouve: ; on a trouvé l’élément JMP Fin2 gauche: MOV BX,DI DEC BX JMP continuer Fin: ; on n’a pas trouvé l’élément FIN2: ret code endp