Title: Les piles
1Les piles
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
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.
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...
5- PUSH AX
- PUSH BX
- MOV AX, 0140
- ADD BX, AX
- MOV 0140, BX
- POP BX
- POP AX
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).
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.
8- PUSH SP lt- SP - 2
- POP SP lt- 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...
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.
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 lopérateur this word (ne pas oublier que
les éléments dun pile sont des mots) crée une
adresse mémoire qui est le mot suivant et
lassigne à bas_pile. Comme les adresse dune
pile sont dans lordre décroissant, cette adresse
en dessous de ladrese du début de la pile.
11- Autrement dit, la déclaration suivante
- First-byte equ this byte
- Word table dw 100 dup(?)
- permet dassigner un nom au premier octet de
ladresse de word-table.
12 13- Suite aux déclarations, il faut écrire une
séquence d'initialisations - ASSUME SSsegment_pile génère une adresse pour
lemplacement 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 quil n'est pas possible de faire
directement MOV SS, segment_pile car cette
instruction n'existe pas!
14Les 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...).
15(No Transcript)
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 - une étiquette (qui représente le nom de la
fonction) précédant - le mot clef PROC marquant le début de la
procédure, - suivi de near (qui signale que la procédure est
située dans le même segment que le programme
appelant) et - RET désignant la dernière instruction,
- et enfin le mot-clé ENDP qui annonce la fin de la
procédure. - Ainsi une déclaration de procédure ressemble à
ceci
17- Etiquette PROC near
- instruction1
- instruction2
- ...
- RET
- Etiquette ENDP
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).
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 dinstruction), 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.
20(No Transcript)
21- Voici un exemple dutilisation 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 quon a écrit le message.
22- Title les procédures
- Pile segment stack
- dw 100 dup (?)
- Basedepile equ thisword
- Pile ends
- data segement
- message db bonjour, monde!, 10,13,
- data ends
- code segment
- assume cscode, dscode, sspile
- debut
- 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
23- ecritmessage proc near notre procédure
- mov ah, 09h
- move dx,offset message
- int 21h
- ret
- ecritmessage endp fin de la procédure/fonction
- code ends fin du segment de code
- end debut fin de la porte dentrée
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 lappel de la fonction...
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 pile
- Cette 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).
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, BP2 Stocke la valeur contenue
dans le mot suivant de la - pile dans BX
(un mot fait 2 octets), sans dépiler
27Exemple avec passage par registre
- 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
28- SOMME PROC near
- AX lt- 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
29Exemple 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, BP6 cette instruction charge le
contenu du mot mémoire d'adresse BP6 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, BP2 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
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, BP2 acquérir dernier
paramètre (DX) sans dépiler pourquoi? - move AX, BP4 acquérir 3ème
paramètre (CX) sans dépiler - move AX, BP6 acquérir 2ème
paramètre (BX) sans dépiler - move AX, BP8 acquérir premeir
paramètre (AX) sans dépiler - ...........
- ret
- soubroutine ends
-
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 sassurer 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.
32Exemple 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 CSSCODE,DSSDATA
- JMP debut
- PGCD proc near déclaration de la
fonction - repet
- MOV AL,CL
- MOV AH,0
- IDIV CH
33- DEBUT
- mov ax,sdata
- mov ds,ax
- mov SI,0 sert dindice tableau
- MOV BX, 5 compteur de nombre à
manipuler - mov CH, valeursSI
- INC SI
- repeter
- CMP BX,0
- JE fin
- mov CL, valeursSI
- Call PGCD
- INC SI
- DEC BX
- JMP repeter
- Fin le PGCD de tous les nombres est dans CH
34- xor ax,ax tout ce qui suit sert à
afficher les chiffres contenus dans le PGCD qui
est dans CH - mov al,ch
- mov si, offset tab_conv
- mov start, offset tab_conv start sert à garder
le début du tableau - mov bx,0
- mov 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 ptrsi,ah
- mov ah,0
- inc si
- jmp division
- fin_div
- add ah,48
- mov byte ptrsi,ah
-
tab_conv contient le nombre converti à lenvers
35- st_bcl
- cmp si,start
- jb fin_bcl
- mov ah , byte ptrsi
- mov byte ptrbx , ah
- dec si
- inc bx
- jmp st_bcl
- fin_bcl
- mov byte ptrbx,10
- inc bx
- mov byte ptrbx,13
- inc bx
- mov byte ptrbx,''
- mov dx,offset tab_sortie
- mov ah,09h
- int 21h
- Sortie MOV AX, 4c00h
- Int 21h
36La 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
37Fonctionnement dune fonctionrécursive
- Création dune pile pour la sauvegarde entre
autres des paramètres dappels de la procédure et
la ladresse de retour.
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.
39- Fonction principale
- entier n nfact
- lire n
- si (n lt 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)
40Fonction factoriel int factoriel(entier n)
si (n lt 1) retourner 1 retourner n
factoriel(n-1)
41Comment le faire en assembleur?
- On a besoin dune pile!
- En effet, à chaque appel récursif, la valeur du
paramètre n est sauvegardée dans la pile de
travail. - Ce processus dempilement est répété jusquà ce
que le paramètre actuel (de lappel) n atteigne
la valeur 0. Cela correspond à la fin de
lexécution de la fonction appelante. - Ensuite, commence le dépilement, et lexécution
de la prochaine instruction de la fonction
appelante est entamée. Ce processus de dépilement
est répété jusquà ce quon atteigne la valeur de
départ du paramètre n.
42Cela se traduit par le programme assembleur
suivant
- TITLE factoriel
- PILE segment stack
- dw 100 dup(?)
- Basdepile equ this word
- PILE ends
- Data segment
- N dw 4
- fact dw ?
- Data ends
- Code segment
- assume CScode, DSData, SSPile
- 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
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édure
- code ends
- end debut fin du programme code
-
44Calcul dune somme par récursivité
- Title sommerecursive pour totaliser la somme de
1 jusquà n. - PILE segment stack
- dw 100 dup(?)
- Basdepile equ this word
- PILE ends
- Data segment
- N dw 12
- som dw ?
- Data ends
- Code segment
- assume CScode, DSData, SSPile
- 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
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
46Les nombres de Fibonacci
- Question Écrire un programme qui calcule le
nombre de Fibonacci défini comme suit
47TITLE fibonacci SPILE SEGMENT STACK DW
100 DUP(?) SPILE ENDS SDATA SEGMENT n dw
6 SDATA ENDS SCODE SEGMENT ASSUME
CSSCODE,DSSDATA 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 21h sortie MOV
AX,4C00H INT 21H
48Fibo proc si1 cmp ax, 1
comparer ax avec 1 ja els
si nlt 1, retourner 1 mov ax, 1
mettre 1 dans ax ret els 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) ret Fibo endp SCODE ENDS
END DEBUT
49Les tours de Hanoï
http//www.multimania.com/fmaire/jeux/han
oi/hanoi.html http//members.aa.net/wgf/Hanoi/H
anoi.html
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.
51- Fonction principale
- entier n
- lire n
- hanoi(n,1,2,3)
- où hanoi satisfait le prototype
- hanoi(entier, entier, entier, entier)
52- Supposons quon 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 saidant de la tour 1.
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 gt 0)
-
- hanoi(n-1, i, k, j)
- écrire "Déplacer i vers k)
- hanoi(n-1, j, i, k)
-
54include ltiostream.hgt void hanoi
(int,int,int,int) void hanoi(int n,int i,int
j,int k) if (ngt0) hanoi(n-1,i,k,j)
cout ltltdéplacer le disque de haut de la
tourltltiltlt à la tour ltltk
hanoi(n-1,j,k,i) main() int n
cingtgtn hanoi(n,1,2,3)
55- Cette fonction est à revoir
- Tours-de-Hanoi PROC NEAR
- push bp
- mov eb,sp
- mov ax,bp4
- 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
56- dohanoi push bp
- mov bp,sp
- mov ax,bp4
- cmp ax,0x0
- jle fini
- dec ax
- push bp 12 empiler le premier appel
récursif - push dword ebp16
- push dword ebp20
- push dword eax
- call dohanoi
- add esp,16
- push dword ebp16 a disk
moved, so print it - push dword ebp12
- call DeplaceLe
- add esp,8
- mov eax,ebp8
- dec eax
- push dword ebp16 empiler le deuxième appel
récursif
57- fini mov esp,ebp
- pop ebp
- ret
- deplaceLe push ebp
- mov ebp,esp
- push dword ebp8
- push dword ebp12
- push dword movestr
- call printf
- add esp,0xc
- mov esp,ebp
- pop ebp
- ret
- Tours-de-Hanoi ENDP
58- Remarquons quil est possible de supprimer
carrément lappel 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.
59Cela se traduit par le programme assembleur
suivant
TITLE factoriel PILE segment stack dw
100 dup(?) Basdepile equ this word PILE
ends Data segment N dw 4 fact dw
? Data ends Code segment assume CScode,
DSData, SSPile 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
60factoriel proc near push ax Continuer
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édure code ends end
debut fin du programme code
61Inversion dune chaine de caractères
- Donnée S une chaine de caractères
- Question Afficher S dans le sens inverse
62- Fonction principale
- ecrire introdroduire la chaîne
- inverser
63- La fonction inverser fonctionne comme suit
- Tant que le caractère lu nest pas le point,
continuer la lecture - Arrivé au point, laffichage commence.
64Entête inverser Corps lire car si
car ltgt . inverser afficher
car
65- TITLE inverser
- affiche macro chaine
- mov dx,offset chaine
- mov ah, 09h
- int 21h
- endm
- PILE segment stack
- dw 100 dup(?)
- Basdepile equ this word
- PILE ends
- Data segment
- Chaine db introduire votre chaine, 10,13,
- Data ends
- Code segment
- assume CScode, DSData, SSPile
- Debut
- MOV AX,Data
- MOV DS,AX
66- inverser Proc near
- Continuer
- mov ah,1 lecture dun
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 depiler
- ret
- inverser fin de la procédure
- code ends fin du programme principal
67- Rechercher lélément C dans un tableau trié dans
lordre croissant.
A
..
C?
milieu
u
L
68 void recherche(C,L,uentier trouvebooleen)
trouve faux si (u lt L) et
(non trouve) milieu (u - L 1)
div 2 si Amilieu C
trouve vrai
sinon si Amilieu gt C
recherche(C,L,milieu-1)
sinon recherche(C,milieu1,u)
69TITLE dichotomique PILE segment stack
dw 100 dup(?) Basdepile equ this word PILE
ends Data segment tableau db 100 dup(?) Valeur
db ? Data ends Code segment assume CScode,
DSData, SSPile 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
dx,offset tableau mov ah,0ah lecture à
partir du clavier dune chaîne de caractères
qui se termine dès quon tape le
retour chariot (touche entrée) int 21h
70- mov SI, offset tableau
- ADD SI,2 adresse du premier élément
- mov BX, tableausi1 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 dichoto
- Fin mov AX,4c00h
- int 21h
- Code ends
- end debut
71Dichoto proc near Continuer CMP
BX, SI JL fin continuer jusquà
il ny 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 tableauDI, 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 continuer trouve on a trouvé lélément
JMP Fin2 gauche MOV BX,DI
DEC BX JMP continuer
Fin on na pas trouvé lélément FIN2 ret
code endp