Langage machine : assembleur 8086 Architectures des ordinateurs Langage machine : assembleur 8086
Références http://lifc.univ-fcomte.fr/~teifreto/ASI-Cours/index.htm http://icps.u-strasbg.fr/~vivien/Enseignement/Archi-2001-2002/Cours.pdf http://asi.insa-rouen.fr/enseignement/siteUV/se/cours.html http://www-gtr.iutv.univ-paris13.fr/Equipe/viennet/Enseignement/ http://www.lifl.fr/~simplot/ens/archi/ http://worldserver.oleane.com/heissler
Plan Architecture d’un processeur Processeur 8086 Assembleur Pile et Procédures Systèmes d’exploitation et appels systèmes
UAL : Rappel Unité chargée Des opérations arithmétiques : ADD (+), SUB (-), MUL (*), DIV (:), INC (+ 1), DEC (- 1) Des opérations logiques : AND, OR, XOR, NOT, CMP LSL, LSR, ASR (décalages)
Architecture de Von Neuman
Chemin des données
Les composants Registres 2 Bus Signaux de commande Adresse, Donnée INST, IP, SP , constantes (0, 1, ...), Registres A, B, C, … Registres tampons (TampA, TampB) Registre des drapeaux de l'UAL (Flags) 2 Bus Signaux de commande Bus 1 : entrée (RO), sortie (AI, TA, TB) UAL : M (sélection de Donnée ou TampA), C (choix de l'opération), FI (mise à jour des Flags) Bus 2 : sortie (DI I, RI) Lecture/ Écriture : DI E , DO
Séquencement des actions Exemple : Reg A Reg A + Reg B Signaux Actions : Transfert (Bus 1) Reg A Tamp A RO10 , TA Transfert (Bus 1) Reg B Tamp B RO11 , TB Choix UAL (C= 100, M= 0, Flags) C 2C1C 0 ,M, FI Transfert (Bus 2) UAL Reg A RI10 Une micro- instruction = ensemble des actions faisant fonctionner une fois le chemin de données
- instruction - instruction = 5 sous- cycles: 1. Transfert n° 1 par le Bus 1 2. Transfert n° 2 par le Bus 1 3. Opération UAL 4. Transfert résultat par le Bus 2 (+ observation des FLAGS) 5. Accès à la mémoire (READ / WRITE)
- programmes (1) 1. Faire l’addition de 2 registres et mettre le résultat dans l’un des deux ex : IP IP + Reg1 10: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL; (signaux: RO1,TA ; RO4,TB ; C= 100 , M= 0 , FI ; RI1 ) 2. Faire des sauts conditionnels : Conditions possibles = FLAGS en sortie de l ’UAL (Bus 2) ex : Si RegA= 0 aller en 30 10: TampA RegA ; TampB Reg0 ; UAL TampA+ TampB; on ZF jmp 30 ; (signaux: RO10,TA ; RO3,TB ; C= 100 , M= 0 , FI ; ) Il faut faire une opération pour calculer ZF mais UAL TampA n ’en est pas une
- programmes (2) 3. Envoyer le contenu d’une case mémoire d’adresse XX dans un registre : (Hypothèse: l’adresse XX est dans un autre registre) ex : RegA [RegB] – il faut commencer par mettre RegB dans Adresse et déclencher une opération de lecture (Un accès à la mémoire (READ / WRITE) prend 2 cycles) 10: Adresse RegB ; ; ; ; READ (signaux: AI , TB ; ; ; ; DIE ) 11: ; ; ; ; READ – la valeur est ensuite disponible dans Donnée . Pour l ’envoyer dans un autre registre, il faut passer par l ’UAL 12: ; ;UAL Donnée ; RegA UAL ; (signaux: ; ; C= 001, M= 1 ; RI10 )
Optimisation Occuper les bus le + possible : ex : RegA [RegB] 10: Adresse RegB ; ; ; ; READ 11: ; ; ; ; READ 12: ; ; UAL Donnée ; RegA UAL ; IP IP + Reg1 13: TampA IP ; TampB Reg1; UAL TampA+ TampB; IP UAL; Ici, on peut faire les 2 opérations en même temps 10: Adresse RegB ; ; ; ; READ 11: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ 12: ; ; UAL Donnée ; RegA UAL ;
L’unité de commande L’unité de commande exécute les opérations suivantes : Lecture du code de l’opération Lecture des arguments Traitement Sauvegarde du résultat Passage à l’instruction suivante -programme de lecture du code de l’opération (l’opération à effectuer est en mémoire à l’adresse IP) - lecture de l ’opération 0: Adresse IP ; ; ; ; READ - on en profite pour passer à la case mémoire suivante 1: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ - exécution du -programme correspondant à l’opération 2: ; ; UAL Donnée ; INST UAL, jmp -Prog[ INST]; 0 : placement du pointeur d’instruction sur le registre d’adresse, aller chercher en mémoire la valeur de l’instruction se trouvant à l’adresse IP 1 : IP = IP + 1 et fin de la lecture 2 : récupération du codop et placement dans INST Puis le code op est envoyé dans une table de conversion qui indique l’adresse du µ-Programme correspondant. Ce µ-Programme est exécuté ligne par ligne : chaque µ-instruction est envoyée dans le registre de µ-instruction où sont générés séquentiellement les signaux de commande de l ’UAL
Add RegA, XX (RegA RegA + [XX]) Exemple 1 Add RegA, XX (RegA RegA + [XX]) L ’UC lit le « codop » de Add RegA dans la mémoire et déclenche le -programme correspondant (0: 1: 2:) 2. Exécution du -programme[ Add RegA, XX] 2. 1 : Lecture de l’argument XX en mémoire lecture de la valeur XX en mémoire (INST [IP]) lecture de la valeur située à l’adresse XX (Donnée [INST]) 2.2 : Traitement de l’opération (RegA RegA + Donnée) 2.3 : Sauvegarde du résultat 2.4 : Passage à l ’instruction suivante (IP IP + 1)
Exemple 1: code - lecture de l ’opération 0: Adresse IP ; ; ; ; READ - on en profite pour passer à la case mémoire suivante 1: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ - exécution du -programme correspondant à l’opération 2: ; ; UAL Donnée ; INST UAL, jmp -Prog[ INST]; - lecture de la valeur de XX en mémoire 20: Adresse IP ; ; ; ; READ 21: TampA IP ;TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ 22: ; ; UAL Donnée ; INST UAL ; - lecture de la valeur située à l’adresse XX 23: Adresse INST ; ; ; ; READ 24: ; ; ; ; READ Traitement de l’opération (RegA RegA + Donnée) 25: ; TampPRegA ;UAL Donnée+TampB ;RegA UAL, jmp 0 ; 20 : placement du pointeur d’instruction sur le registre d’adresse, aller chercher en mémoire la valeur de XX en mémoire 21 : IP = IP + 1 et fin de la lecture 22 : récupération de la valeur de XX et placement dans INST 23 : placement de INST sur le registre d’adresse, aller chercher en mémoire la valeur située à l’adresse XX 24 : fin de lecture 25 : Traitement de l’opération et retour à l’instruction suivante
JZ xx (va en IP+ xx+ 1 si le résultat de l ’UAL est nul) Exemple 2 JZ xx (va en IP+ xx+ 1 si le résultat de l ’UAL est nul) 1. L ’UC lit le « codop » de JZ dans la mémoire et déclenche le -programme correspondant (0: 1: 2:) 2. Exécution de -programme[ JZ XX] 2. 1 : Lecture de l ’argument XX en mémoire (Donnée [IP]) 2. 2 : Traitement de l ’opération (Test sur ZF, IP IP+ 1+ xx) (2.3 : Sauvegarde du résultat) 2. 4 : Passage à l ’instruction suivante si la condition n ’est pas réalisée
Exemple 2 : code L ’UC lit le « codop » de JZ dans la mémoire et déclenche le -programme correspondant (0: 1: 2:) 0: Adresse IP ; ; ; ; READ 1: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ 2: ; ; UAL Donnée ; INST UAL, jmp -Prog[ INST]; 2. Exécution de -programme[ JZ XX] 2. 1 : Lecture de l ’argument XX en mémoire (Donnée [IP]) 2. 2 : Traitement de l ’opération (Test sur ZF, IP IP+ 1+ xx) (2.3 : Sauvegarde du résultat) 2. 4 : Passage à l ’instruction suivante si la condition n ’est pas réalisée 30: Adresse IP ; ; ; on ZF jmp 32 ; READ 31: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL, jmp 0 ; 32: TampA IP ; TampB Reg1 ; UAL TampA+ TampB ; IP UAL ; READ 33: ; TampB IP ; UAL Donnée+ TampB ; IP UAL, jmp 0 ; 30 : placement du pointeur d’instruction sur le registre d’adresse, si résultat UAL = 0 jmp 32, aller chercher en mémoire la valeur de XX (IP dans adresse) 31 : (UAL différent de 0) on met dans IP la valeur IP + 1 et instruction suivante 32 : on met dans IP la valeur IP + 1 et on finit la lecture de XX 33 : IP = IP + valeur de XX enfin reçue
Code opération : assembleur Programme en langage machine 80486 implanté à l’adresse mémoire 0100H A1 01 10 03 06 01 12 A3 01 14 Ce programme additionne le contenu de deux cases mémoire et range le résultat dans une troisième Voici une transcription langage symbolique du programme complet. L'adresse de début de chaque instruction est indiquée à gauche (en hexadécimal). Adresse Contenu MP Langage Symbolique Explication en francais 0100 A1 01 10 MOV AX, [0110] Charger AX avec le contenu de 0110. 0103 03 06 01 12 ADD AX, [0112] Ajouter le contenu de 0112 a AX (resultat dans AX). 0107 A3 01 14 MOV [0114],AX Ranger AX en 0114.
Code opération : assembleur Symbole Code Op. Octets MOV AX, valeur B8 3 AX valeur MOV AX, [ adr ] A1 AX contenu de l'adresse adr. MOV [ adr ], AX A3 range AX à l'adresse adr. ADD AX, valeur 05 AX AX + valeur ADD AX, [ adr ] 03 06 4 AX AX + contenu de adr. SUB AX, valeur 2D AX AX - valeur SUB AX, [ adr ] 2B 06 AX AX - contenu de adr. SHR AX, 1 D1 E8 2 décale AX à droite. On utilise des programmes spéciaux, appelés assembleurs, pour traduire automatiquement le langage symbolique en code machine.
Fonctionnement de l’UC L ’UC possède un registre spécial pour stocker la -instruction en cours
Autre représentation (1)
Autre représentation (2)
Fonctionnement de l’UC A partir du registre de µ-instruction, il faut générer les signaux de commande de l’UAL dans un ordre précis …
Séquencement des opérations Chaque partie de -INST est reliée à un DCD (ou un DMX) qui déclenchera le bon signal de commande, au bon moment : Ex : R3 = registre destination de la sortie de l’UAL par le Bus 2 (DI I , RI 0 … RI 15 )
Signal d’horloge CK CK i = Sous- cycles de CK correspondants aux sous-cycles des -instructions Une fréquence d'horloge d'un microprocesseur à 500MHz donne des cycles élémentaires de 2 nanosecondes.
Schéma de l’unité de commande
Schéma de l’unité de commande Lorsqu’une instruction arrive dans RI, son Codop est envoyé dans une table de conversion qui indique l’adresse du -Programme correspondant. Ce -Programme est exécuté ligne par ligne : chaque -instruction est envoyée dans le registre de -instruction où sont générés séquentiellement les signaux de commande de l ’UAL
Schéma
MMI, RMI et MCO MMI ou mémoire de micro-instructions = élément central de la logique de contrôle RMI (son registre associé) contient une micro instruction (tps t) La MMI, généralement une mémoire morte, contient toutes les micro-instructions qui sont nécessaires au processeur pour exécuter les instructions du langage machine. MCO, ou compteur ordinal du microprogramme : Il s'agit d'un registre qui contient l'adresse de la prochaine micro instruction à exécuter c'est-à-dire celle qui doit être placée dans le RMI, seul lieu où une micro instruction peut agir sur le circuit de données.
Niveaux de programmation
Technologies de processeurs CISC (Intel 8086, Pentium…, Motorola) Complex Instruction Set Computer : calculateur à jeu d'instructions complexe. Caractérise les microprocesseurs qui disposent d'un jeu étendu d'instructions avec de nombreux modes d'adressage. La plupart ne sert que dans des cas relativement rares. Ces instructions complexes nécessitent d'être micro-codées et s'exécutent donc en plusieurs cycles. RISC : IBM/Motorola (PowerPC),SUN (Supersparc), DIGITAL (Alpha) Reduced Instruction Set Computer : calculateur à jeu d'instructions réduit. En utilisateur un jeu d'instructions plus réduit que la technologie CISC, les processeurs RISC peuvent disposer d'un jeu d'instructions entièrement cablé (donc sans microcode) ce qui permet une exécution des instructions en un cycle.
La mémoire cache Depuis pas mal d'années, les circuits de mémoire ne sont plus assez rapides pour suivre la cadence des microprocesseurs on intercale entre le microprocesseur et la mémoire RAM, une autre mémoire allant à la même vitesse que le microprocesseur celle-ci est de taille assez réduite car elle coûte bien plus cher que la mémoire RAM standard souvent, il y a deux caches, un pour le programme et un pour les données Augmentation de la taille des bus d’adresses et de données Le micro-processeur est alimenté plus vite Bus d’adresse à 32 ou 64 bits = architecture à 32 ou 64 bits
Le cache processeur cache 80386 80486 1 cache interne 8Ko pentium 80486 1 cache interne 8Ko pentium 1 cache interne donnée 8 Ko et 1 cache interne instructions 8 Ko pentium 2 1 cache interne donnée 16 Ko et 1 cache interne instructions 16 Ko 1 cache externe 256 Ko commun au 2 caches internes pentium 3
Le Pipeline Un pipeline est composé de plusieurs étages chacun de ces étages est dédié à un traitement particulier Dans un processeur sans pipeline, les instructions sont exécutées les unes après les autres il ne rentrera une nouvelle instruction dans le pipeline que lorsque l'instruction précédente est passée par tous les étages et est terminée le processeur n'utilise qu'un seul étage à la fois, donc les autres étages sont inactifs. Avec un processeur à 5 étages sans pipeline
Le Pilpeline But : utiliser tous les étages en même temps lorsqu'une instruction est dans un étage, 4 autres instructions sont en cours de traitement. grâce au débit de la mémoire cache de niveau 1 les instructions peuvent s'enchaîner suffisamment vite pour que le pipeline soit constamment alimenté.
Processeurs superscalaires Un microprocesseur est de type superscalaire quand il intègre plus d'une unité entière (ALU) en con cœur. les deux unités sont indépendantes et fonctionnent en parallèle, chacune se charge d'exécuter une instruction sur deux. Il est ainsi possible d'exécuter deux instructions par cycle d'horloge.
Coprocesseurs mathématiques Jusqu'au 386, celui-ci était parfois assisté par un coprocesseur mathématique optionnel permettant d'accroître les capacités de calcul en virgule flottante (très utilisé par les tableurs et les logiciels de traitement graphique). Aujourd’hui, ce coprocesseur fait partie intégrante du CPU.
Efficacité architecturale Croissance du nombre d’instructions exécutées par cycle d’horloge
Plan Architecture d’un processeur Processeur 8086 Assembleur Pile et Procédures Systèmes d’exploitation et appels systèmes
Processeurs 80x86 Micro-processeurs 80x86 équipent les PC et compatibles Premiers PC (début 80) = 8086, micro-processeur 16 bits Puis 80286, 80386, 80486, Pentium… Augmentation de la fréquence d’horloge, de la largeur des bus d’adresses et de données Ajout de nouvelles instructions et de registres Compatibilité ascendante Un programme écrit dans le langage machine du 286 peut s’exécuter sur un 386 (l’inverse est faux) En TP on utilisera un assembleur 8086
Caractéristiques du 8086 Bus de données : 16 bits Bus d’adresse : 20 bits Registres : 16 bits 4 accumulateurs 16 bits Accumulateur (AX) Base (BX) Counter (CX) Accumulateur auxiliaire (DX) Registres accessibles sous forme de 2 info 8 bits AX se décompose en AH (poids fort) et AL (poids faible de AX)…
Caractéristiques du 8086 4 accumulateurs 16 bits Registres d’index : AX, BX, CX ,DX Registres d’index : Pointeur d’instruction (IP) Index source ou destination(SI, DI) Pointeur de Pile ou de base (SP, BP) 3+1 registres segment : Segment de code (CS) : contient le prog en cours d’exécution Segment data (DS) : contient les données du programme Segment stack (SS) : contient des données particulières Extra Segment (ES)
Segmentation de la mémoire Largeur du bus d’adresse = 20 bits Possibilité d’adressage mémoire = 220 = 1 Mo Le pointeur d’instruction fait 16 bits Possibilité d’adresser 216 = 64 Ko (ce qui ne couvre pas la mémoire) On utilise deux registres pour indiquer une adresse au processeur Chaque segment débute à l'endroit spécifié par un registre spécial nommé registre segment. Le déplacement permet de trouver une information à l'intérieur du segment. CS:IP : lecture du code d’une instruction (CS registre segment et IP déplacement) DS : accès aux données (MOV AX,[1045] = lecture du mot mémoire d’adresse DS:1045H)
Segmentation de la mémoire Registres de déplacement = sélectionner une information dans un segment. Dans le segment de code CS : le compteur de programme IP joue ce rôle. CS:IP permet d'accéder à une information dans le segment de code. Dans les segments de DS : les deux index SI ou DI jouent ce rôle. Le déplacement peut être aussi une constante. DS:SI ou DS:DI permettent d'accéder à une information dans le segment de données. Dans le segment de pile SS le registre SP (stack pointer) et BP (base pointer) jouent ce rôle. SS:SP ou SS:BP permettent d'accéder à une information dans le segment de pile.
Jeu d’instruction (1) Instruction d’affectation : MOV (Transfert CPU Mémoire) Instructions arithmétiques : INC (incrémentation) (Opération Acc / Donnée) : DEC (décrementation) : ADD (addition) : SUB (soustraction) : CMP (soustraction sans sauvegarde) : NEG Instructions logiques : NOT, OR, XOR : AND, TEST (= AND sans sauvegarde) : SHL (SHR), SAL (SAR) : ROL (ROR), RCL (RCR)
Jeu d’instruction (2) Branchement : JMP Branchements conditionnels : JE/ JZ (JNE/ JNZ) : Jump if zero : JO (JNO) : Jump if overflow : JS (JNS) : Jump if sign Comparaison de valeurs CMP AX, BX suivi d ’un test : (entiers naturels) (complément à 2) AX > BX ? JA ( >= JAE) JG (JGE) AX < BX ? JB (JBE) JL (JLE)
Branchements Le processeur exécute une instruction en mémoire puis passe à celle qui suit en mémoire : séquentiel Besoin de faire répéter au processeur une suite d’instructions Besoin de déclencher une action qui dépend d’un test Utilisation d’une instruction de branchement ou saut On indique au processeur l’adresse de la prochaine instruction On distingue deux catégories de branchements le saut est toujours effectué (sauts inconditionnels) il est effectué seulement si une condition est vérifiée (sauts conditionnels).
Rappel sur le registre IP Le registre IP du processeur conserve l'adresse de la prochaine instruction à exécuter Le processeur effectue les actions suivantes pour chaque instruction : lire et décoder l'instruction à l'adresse IP; IP IP + taille de l'instruction; exécuter l'instruction. Pour modifier le déroulement normal d'un programme l'exécution de l'instruction doit modifier la valeur de IP c'est ce que font les instructions de branchement.
Sauts inconditionnels Principale instruction de saut inconditionnel = JMP L'opérande de JMP est un déplacement, c'est à dire une valeur qui va être ajoutée à IP. L'action effectuée par JMP est : IP = IP + déplacement Le déplacement est un entier relatif codé sur 8 bits. La valeur du déplacement est : déplacement = adr. instruction visée - adr. instruction suivante
Sauts inconditionnels : exemple Exemple : le programme suivant écrit indéfiniment la valeur 0 à l'adresse 0140H. La première instruction est implantée à l'adresse 100H. Adresse Contenu MP Langage Symbolique Explication en français 0100 B8 00 00 MOV AX, 0 met AX a zéro 0103 A3 01 40 MOV [140], AX écrit à l'adresse 140 0106 EB FC JMP 0103 branche en 103 0107 xxx -> instruction jamais exécutée Le déplacement est ici égal à FCH, c'est à dire -4 (=103H-107H).
Indicateurs Les instructions de branchement conditionnels utilisent les indicateurs, bits spéciaux positionnés par l'UAL après certaines opérations. nous étudierons ici les indicateurs nommés ZF, CF, SF et OF. ZF : Zero Flag Cet indicateur est mis à 1 lorsque le résultat de la dernière opération est zéro. Sinon, ZF est positionné à 0. CF : Carry Flag C'est l'indicateur de report (retenue). Il est positionné par les instructions ADD, SUB et CMP (entiers naturels). CF = 1 s'il y a une retenue
Indicateurs (suite) SF : Sign Flag SF est positionné à 1 si le bit de poids fort du résultat d'une addition ou soustraction est 1; sinon SF=0. SF est utile lorsque l'on manipule des entiers relatifs, car le bit de poids fort donne alors le signe du résultat. OF : Overflow Flag (Indicateur de débordement) OF=1 si le résultat d'une addition ou soustraction donne un nombre qui n'est pas codable en relatif dans l'accumulateur (par exemple si l'addition de 2 nombres positifs donne un codage négatif). CMP = SUB, mais ne stocke pas le résultat de la soustraction (positionner les indicateurs) CMP AX, 5 : ZF = 1 si AX contient 5, et ZF = 0 si AX 5.
Sauts conditionnels : exemples JE Jump if Equal (ou JZ) saut si ZF = 1; JNE Jump if Not Equal (ou JNZ) saut si ZF = 0; JG Jump if Greater saut si ZF = 0 et SF = OF; JLE Jump if Lower or Equal saut si ZF=1 ou SF OF; JS (JNS) Jump if Sign saut si SF=1; JA Jump if Above saut si CF=0 et ZF=0; JBE Jump if Below or Equal saut si CF=1 ou ZF=1. JB Jump if Below saut si CF=1. JO (JNO) Jump if Overflow saut si OF=1…
Décalage et rotations Décalage vers la gauche ou vers la droite les bits de l'accumulateur. opérations utilisées pour décoder bit à bit des données ou pour diviser ou multiplier rapidement par une puissance de 2. En effet : décaler AX de n bits vers la gauche revient à le multiplier par 2n De même, un décalage vers la droite revient à diviser par 2n. Ces opérations peuvent opérer sur les registres AX ou BX (16 bits) ou sur les registres de 8 bits AH, AL, BH et BL. SHL, SHR, ROL, ROR, RCL, RCR…
Décalage SHL registre, 1 (Shift Left) Décale les bits du registre d'une position vers la gauche. Le bit de gauche est transféré dans l'indicateur CF. Les bits introduits à droite sont à zéro. SHR registre, 1 (Shift Right) Comme SHL mais vers la droite. Le bit de droite est transféré dans CF. SHL et SHR peuvent être utilisé pour multiplier/diviser des entiers naturels (et non des relatifs car le bit de signe est perdu)
Rotations ROL registre, 1 (Rotate Left) Rotation vers la gauche : le bit de poids fort passe à droite, et est aussi copié dans CF. Les autres bits sont décalés d'une position. ROR registre, 1 (Rotate Right) Comme ROL, mais à droite.
Décalage et rotations RCL registre, 1 (Rotate Carry Left) Rotation vers la gauche en passant par l'indicateur CF. CF prend la place du bit de poids faible; le bit de poids fort part dans CF. RCR registre, 1 (Rotate Carry Right) Comme RCL, mais vers la droite. RCL et RCR sont utiles pour lire bit à bit le contenu d'un registre7.
Opérations logiques 3 opérateurs logiques : ET, OU et OU exclusif. jamais propagation de retenue lors de ces opérations (chaque bit du résultat est calculé indépendamment des autres) Opérations sont de la forme : OR destination, source destination : registre ou emplacement mémoire (adresse) où doit être placé le résultat. source : constante (adressage immédiat), registre (adressage implicite), ou adresse (adressage direct). OR AX, FF00 ; AX <- AX ou FFOO OR AX, BX ; AX <- AX ou BX OR AX, [1492] ; AX <- AX ou [1492]
Opérations logiques OR destination, source (OU : 1 ou 0 =1 ; 1 ou 1 = 1…) OR est souvent utilisé pour forcer certains bits à 1. Par exemple après OR AX, FF00, l'octet de poids fort de AX vaut FF, tandis que l'octet de poids faible est inchangé. AND destination, source (ET : 1 et 1 = 1 …) AND est souvent utilisé pour forcer certains bits à 0. Après AND AX, FF00, l'octet de poids faible de AX vaut 00, tandis que l'octet de poids fort est inchangé. XOR destination, source (OU EXCLUSIF : 1 xor 1 = 0…) XOR est souvent utilisé pour inverser certains bits. Après XOR AX, FFFF, tous les bits de AX sont inversés
Codage Les instructions et leurs opérandes (paramètres) sont stockés en mémoire principale La taille totale d'une instruction (nombre de bits nécessaires pour la représenter en mémoire) dépend du type d'instruction et aussi du type d'opérande. Chaque instruction est toujours codée sur un nombre entier d'octets, afin de faciliter son décodage par le processeur. Une instruction est composée de deux champs : le code opération, qui indique au processeur quelle instruction réaliser; le champ opérande qui contient la donnée, ou la référence à une donnée en mémoire (son adresse).
Codage Selon la manière dont la donnée est spécifiée, c'est à dire selon le mode d'adressage de la donnée, une instruction sera codée par 1, 2, 3 ou 4 octets. Nous distinguerons ici quatre modes d'adressage : Implicite immédiat direct relatif
Types d’adressage Adressage implicite ou par registre ADD AX, BX INC AX Pas d’accès mémoire pour les opérandes L'instruction contient seulement le code opération, sur 1 ou 2 octets. L'instruction porte sur des registres ou spécifie une opération sans opérande
Types d’adressage Adressage immédiat ADD AX, valeur 1 accès mémoire pour lire la valeur Le champ opérande contient la donnée (une valeur constante sur 1 ou 2 octets). Exemple : ``Ajouter la valeur 5 à AX''. Ici l'opérande 5 est codée sur 2 octets puisque l'opération porte sur un registre 16 bits (AX).
Types d’adressage Adressage direct ADD AX, [adresse] 2 accès mémoire : adresse puis valeur Le champ opérande contient l'adresse de la donnée en mémoire principale sur 2 octets. Attention : dans le 80x86, les adresses sont toujours manipulées sur 16 bits, quelle que soit la taille réelle du bus. Exemple : ``Placer dans AX la valeur contenue à l'adresse 130H''.
Types d’adressage Adressage relatif ou indexé ADD AX, [adresse+index] MOV AX, [SI+1] 2 accès mémoire Ce mode d'adressage est utilisé pour certaines instructions de branchement. Le champ opérande contient un entier relatif codé sur 1 octet, nommé déplacement, qui sera ajouté à la valeur courante de IP.
Plan Architecture d’un processeur Processeur 8086 Assembleur Pile et Procédures Systèmes d’exploitation et appels systèmes
Code opération : assembleur Programme en langage machine 80486 implanté à l’adresse mémoire 0100H A1 01 10 03 06 01 12 A3 01 14 Ce programme additionne le contenu de deux cases mémoire et range le résultat dans une troisième Voici une transcription langage symbolique du programme complet. L'adresse de début de chaque instruction est indiquée à gauche (en hexadécimal). Adresse Contenu MP Langage Symbolique Explication en francais 0100 A1 01 10 MOV AX, [0110] Charger AX avec le contenu de 0110. 0103 03 06 01 12 ADD AX, [0112] Ajouter le contenu de 0112 a AX (resultat dans AX). 0107 A3 01 14 MOV [0114],AX Ranger AX en 0114.
Code opération : assembleur Symbole Code Op. Octets MOV AX, valeur B8 3 AX valeur MOV AX, [ adr ] A1 AX contenu de l'adresse adr. MOV [ adr ], AX A3 range AX à l'adresse adr. ADD AX, valeur 05 AX AX + valeur ADD AX, [ adr ] 03 06 4 AX AX + contenu de adr. SUB AX, valeur 2D AX AX - valeur SUB AX, [ adr ] 2B 06 AX AX - contenu de adr. SHR AX, 1 D1 E8 2 décale AX à droite. On utilise des programmes spéciaux, appelés assembleurs, pour traduire automatiquement le langage symbolique en code machine.
Processus d’assemblage 3 phases : Saisie du code source avec un éditeur de texte Compilation du code source Édition des liens permet de lier plusieurs codes objets en un seul exécutable permet d ’inclure des fonctions prédéfinies dans des bibliothèques
Assembleur : NASM [BITS 16] [ORG 0x0100] Val equ 12 Var1 db 69 [SEGMENT .text] BEGIN: jmp START FIN: mov ax, 0x4C00 int 0x21 START: mov [Var1], 3 jmp FIN Val equ 12 Var1 db 69 Var2 dw 0FFFFh Tab resb 100
En-tête [BITS16] : indique au compilateur qu’on travaille en mode 16 bits (programme DOS) [ORG 0x100] : le programme est chargé en mémoire à partir de l’adresse 0x100h (programme .com) [SEGMENT .text] : déclaration du segment dans lequel on travaille, dans un programme .com : 1 seul segment pour le code et les données [int 0x20] : Interruption = appel système pour rendre la main au dos
Variables DB : Variable 8 bits DW : Variable 16 bits EQU : Constante RESB : Variable 8 bits (tableau) RESW : Variable 16 bits (tableau) BYTE : Taille d'une variable mémoire 8 bits WORD : Taille d'une variable mémoire 16 bits Etiquette : adresse d’une méthode/ branchement
Variables DB : Variable 8 bits DW : Variable 16 bits EQU : Constante RESB : Variable 8 bits (tableau) RESW : Variable 16 bits (tableau) BYTE : Taille d'une variable mémoire 8 bits WORD : Taille d'une variable mémoire 16 bits Etiquette : adresse d’une méthode/ branchement
Représentation mémoire : .com CS, DS, SS Header DOS 100h IP Programme 64 Ko Variables SP
Fichier .com Au début du programme Un seul segment de 64 Ko pour les données le programme et la pile .exe : on peut avoir un segment pour chaque Au début du programme IP pointe sur l’adresse 100h du segment (header DOS) CS, DS, SS pointent au début SP pointe à la fin (tête de pile) : attention que votre pile n’écrase pas votre programme ou vos données
Exemple de programme NASM mov ah,02h mov dl,4Ah int 21h int 20h org 100h ;affichage de B mov ah,02h mov dl,42h int 21h ;affichage de O mov dl,4Fh ;affichage de N mov dl,4Eh mov AX,0x13 : mode 13 du mode graphique pour l’appel système (13 : 320*200, 256 couleurs, linéaire) int 0x10 : appel système utilisant AX mov AX,0xA000 : adresse de la mémoire vidéo mov ES,AX : on n’a pas le droit de faire directement mov ES, 0xA000 on passe donc par AX mov DI,6720 : DI offset d’un pixel calculé selon la méthode 320*y+x boucle: mov byte [ES:DI],5 : on affecte la couleur 5 au point d’adresse ES:DI add DI,321 : on se place 321 pixels plus loin donc à la ligne suivante cmp DI,12000 : lorsqu’on atteint le pixel d’offset 12000 on arrête jb boucle int 0x20 : on rend la main au dos
Plan Architecture d’un processeur Processeur 8086 Assembleur Pile et Procédures Systèmes d’exploitation et appels systèmes
Pile Structure de « rangement » de données Comment y accéder : définie dans un segment de mémoire particulier (.exe) ou dans le même que le code et les données (.com) fonctionnement LIFO (Last In, First Out) Comment y accéder : adresse du dernier élément posé : SS:SP empiler : PUSH Reg16 (registre 16 bits) dépiler : POP Reg16 (registre 16 bits) La pile augmente vers les adresses faibles PUSH : SP SP- 2, POP : SP SP+ 2
Pile : exemple d’utilisation (1) PUSH registre empile le contenu du registre sur la pile. POP registre retire la valeur en haut de la pile et la place dans le registres spécifié. Exemple : transfert de AX vers BX en passant par la pile. PUSH AX ; Pile <- AX POP BX ; BX <- Pile Note : cet exemple n'est pas très utile, il vaut mieux employer MOV AX, BX.)
Pile : exemple d’utilisation (2) La pile est souvent utilisée pour sauvegarder temporairement le contenu des registres : ;AX et BX contiennent des données a conserver PUSH AX PUSH BX MOV AX, 5 MOV BX, 4 ; on utilise AX ADD AX, BX ; et BX POP BX ; récupère l'ancien BX POP AX ; et l'ancien AX On voit que la pile peut conserver plusieurs valeurs. La valeur dépilée par POP est la dernière valeur empilée; c'est pourquoi on parle ici de pile LIFO (Last In First Out, Premier Entré Dernier Sorti).
Pile : registres SS et SP 16 bits Le registre SS (Stack Segment) = registre segment qui contient l'adresse du segment de pile courant (16 bits de poids fort de l'adresse). Il est normalement initialisé au début du programme et reste fixé par la suite. Le registre SP (Stack Pointer) contient le déplacement du sommet de la pile (16 bits de poids faible de son adresse). PUSH POP SP
Pile : registres SP L'instruction POP effectue le travail inverse : L'instruction PUSH effectue les opérations suivantes : SP SP - 2 [SP] valeur du registre 16 bits. Notons qu'au début (pile vide), SP pointe ``sous'' la pile L'instruction POP effectue le travail inverse : registre destination [SP] SP SP + 2 Si la pile est vide, POP va lire une valeur en dehors de l'espace pile, donc imprévisible.
Pile : registres SP SP-2 SP 16 bits Emplacement libre Adresses Croissantes SP-2 SP PUSH POP
Procédures (1) Déclaration d’une procédure : nous utiliserons une étiquette ou label pour définir le début et le nom d’une procédure Appel de la procédure dans le programme CALL NEAR label ... CALL NEAR affiche affiche : MOV AH,9 INT 0x21 RETN
Procédures (2) Comment l’unité de traitement arrive-t-elle à retourner au programme principal à la fin de la procédure ? Au moment de l’appel de la fonction, l’adresse de l’instruction suivante est sauvegardée dans la pile : sauvegarde de IP A la fin de la procédure, l ’Unité de Traitement récupère les valeurs sauvegardées pour retourner au programme principal RETN = dépilement de IP
Passage de paramètres 2 méthodes de passage de paramètres : par registre par la pile Passage de paramètres par registre : les paramètres d’entrée de la procédure sont mis dans des registres avant l’appel de la procédure les paramètres de sortie sont aussi rangés dans des registres avantage = rapidité inconvénients = peu de registres
Passage par registre ;programme principal ;Procédure ... Moyenne : Mov AX, N1 Mov BX, N2 Call Near Moyenne Mov Res, AX ;Procédure Moyenne : Add AX, BX SHR AX, 1 RETN Retn = dépilement de IP pour retourner au programme principal
Passage par la pile (1) Les paramètres d’entrée sont empilés avant l’appel de la procédure Les paramètres de sortie sont dépilés par le programme principal avantage = « portabilité » inconvénients = récupération des paramètres plus « lourde » ;Procédure Moyenne : PUSH BP Mov BP, SP Mov AX, [BP+4] Add AX, [BP+6] SHR AX, 1 Mov [BP+ 6], AX POP BP Retn 2 ;programme ... PUSH N1 PUSH N2 Call Near Moyenne POP Res
Passage par la pile (2) Évolution de la pile A quoi sert BP ? BP = référence de la pile au début de la procédure permet d’avoir une référence fixe pour récupérer les paramètres ici : [BP+ 4] pour N2 et [BP+ 6] pour N1
Passage par la pile (3) Sauvegarde du résultat et nettoyage de la pile
Rappels : Registres de segment Nom Taille Fonction Cs (Code Segment) 16 bits Mémorise le segment où se trouve le code en cours d'exécution (ne peut pas être modifié par le programme) Ds (Data Segment) 16 bits Mémorise le segment où se trouve les données du programme. Ss (Stack Segment) 16 bits Mémorise le segment où se trouve la pile de données du programme Es (Extra Segment) 16 bits Ce segment peut être utilisé pour faire ce que l'on veut. Par exemple, il peut pointer sur la mémoire écran.
Rappels : Registres de travail Nom Taille Fonction Ax (Accumulateur) 16 bits On l'utilise généralement pour des opérations arithmétiques, telles que MUL (multiplication) ou DIV (division). Ax peut se diviser en deux sous-registres de 8 bits. Ah représente les 8 premiers bits, et Al les 8 derniers. Bx (Base) 16 bits Bx est utilisé lors de l'accès à une zone mémoire sous forme de tableau, il représente l'indice de ce tableau. Par exemple, on écrira Mov Dx, Es:[Bx]. Bx peut se diviser en deux sous-registres de 8 bits. Bh représente les 8 premiers bits, et Bl les 8 derniers.
Rappels : Registres de travail Nom Taille Fonction Cx (Compteur) 16 bits Lors de l'appel d'instructions comme REP (répéter) ou LOOP (boucle), c'est le registre Cx qui est lu Cx peut se diviser en deux sous- registres de 8 bits. Ch représente les premiers bits, et Cl les 8 derniers. Dx (Données) 16 bits Ce registre est généralement utilisé pour stocker des données provisoires. Dx peut se diviser en deux sous-registres de 8 bits. Dh représente les 8 premiers bits, et D les 8 derniers.
Rappels : Registres d'offset (à combiner avec une adresse de segment) Nom Taille Fonction Si (Source Index) 16 bits Lors d'opérations sur les chaînes de caractères, comme MOVSB ou SCASB, Ds:[Si] désigne la variable 'source'. Di (Dest Index) 16 bits Lors d'opérations sur les chaînes de caractères, comme MOVSB ou SCASB, Es:[Di] désigne la variable 'destination'. Bp (Base Pointeur) 16 bits Bp a un rôle proche de celui de Bx, mais il est généralement utilisé avec le segment de pile (Ss:[Bp]).
Rappels : Registres d'offset (à combiner avec une adresse de segment) Nom Taille Fonction Ip (Instruction Point)16 bits Cs:[Ip] indique la prochaine instruction à exécuter. Tout comme Cs, Ip ne peut être manipulé par le programme exécuté. Sp (Stack Pointeur) 16 bits Ss:[Sp] indique le dernier élément de la pile. Chaque opération PUSH (empiler) ou POP (dépiler) modifie le registre Sp.
Exemple de programme NASM [BITS 16] [ORG 0x100] [SEGMENT .text] PILE PROC mov AX,0x13 : mode 13 du mode graphique pour l’appel système (13 : 320*200, 256 couleurs, linéaire) int 0x10 : appel système utilisant AX mov AX,0xA000 : adresse de la mémoire vidéo mov ES,AX : on n’a pas le droit de faire directement mov ES, 0xA000 on passe donc par AX mov DI,6720 : DI offset d’un pixel calculé selon la méthode 320*y+x boucle: mov byte [ES:DI],5 : on affecte la couleur 5 au point d’adresse ES:DI add DI,321 : on se place 321 pixels plus loin donc à la ligne suivante cmp DI,12000 : lorsqu’on atteint le pixel d’offset 12000 on arrête jb boucle int 0x20 : on rend la main au dos
Plan Architecture d’un processeur Processeur 8086 Assembleur Pile et Procédures Systèmes d’exploitation et appels systèmes
Interpréteur et compilateur (1) On distingue grossièrement deux familles de langages informatique les langages interprétés les langages compilés Un programme en langage interprété va être traduit au fur et à mesure de son exécution par un interpréteur interpréteur : programme chargé de décoder chaque instruction du langage et d'exécuter les actions correspondantes Programmes compilés : traduction en langage machine a lieu une fois pour toute. Le compilateur (traducteur) traduit chaque instruction du langage en une suite d'instructions en langage machine
Interpréteur et compilateur (2) Les programmes compilés s'exécutent ainsi plus rapidement que les programmes interprétés La traduction est déjà faite Mais on perd en souplesse de programmation, car les types de données doivent être connus au moment de la compilation Compilateur = traduit un programme source écrit dans un langage de haut niveau (C) en un autre programme dans un langage de bas niveau (par exemple l'assembleur) Opération de traduction complexe Compilateurs = programmes sophistiqués
Principaux langages Quelques langages interprétés : Les principaux langages compilés sont : C/C++ : programmation système et scientifique ADA : logiciels embarqués Cobol : gestion Fortran : calcul scientifique Pascal : enseignement Quelques langages interprétés : BASIC : bricolage LISP, Prolog : Intelligence Artificielle Python : programmation système, Internet Java : applets internet MATLAB : calcul scientifique LISP, Java ou Python : une première phase de compilation vers un langage intermédiaire (bytecode), qui sera lui même interprété.
Compilation du C Traduction en assembleur des programmes en langage C Le détail de cette traduction (ou compilation) dépend Compilateur utilisé Système d'exploitation (DOS, Windows, UNIX,...). Taille des types : exemple int (16 ou 32 bits) Modèle de mémoire utilisé (pointeurs sur 16 ou 32 bits, données et code dans des segments différents ou non, etc.) Exemple : compilateur Turbo C++ version 3 sous DOS (entiers de 16 bits et le modèle de mémoire « small ») Génère directement du code objet (fichier .OBJ) à partir d'un fichier source en langage C Il est cependant possible de demander l'arrêt de la compilation pour obtenir du langage assembleur (fichier .ASM)
C et assembleur Introduction d’instructions assembleur dans des programmes en langage C (ou C++). Programme non portable, car le langage assembleur diffère d'un type d'ordinateur à l'autre Pour un programme utilisant les ressources matérielles d'une machine : plus confortable d'écrire un programme C contenant quelques lignes d'assembleur que de tout écrire en assembleur. Exemple avec Turbo C++/TASM void main(void) { int A = 20; asm{ MOV AX, A SHL AX, 1 } printf(’’AX =%d\n’’,_AX); Ce programme affiche 40.
Système d’exploitation OS : Operating System : le programme permettant d'utiliser les circuits qui ont été câblés. Soit entièrement en ROM Soit un code de boot en ROM se chargeant de placer en RAM le reste de l'OS à partir de la disquette ou du DD Souvent, une ROM de boot contient néanmoins la partie de l'OS la plus primitive: le BIOS. But de l'OS = décharger le programme des tâches répétitives et de bas niveau. Gain de temps lors du développement programmes Pas à se soucier du fonctionnement de la circuiterie électronique
Système d’exploitation Le système d’exploitation doit s’occuper de : l ’exécution des commandes d’entrée/ sortie la gestion de la mémoire la gestion des fichiers la multi- programmation (« multi- tâche ») Comment exécuter plusieurs programmes à la fois ? Et si ces programmes veulent tous accéder à l ’imprimante en même temps ? Et s’ils doivent échanger des informations ?… Comment exécuter un seul programme avec plusieurs processeurs ? la sécurité (gestion des accès,…) Le SE doit aussi fournir : un langage de commande divers utilitaires (compilateurs, éditeurs, outils, …) une interface graphique pour l’utilisateur
Système d’exploitation Windows 95/ 98, Windows NT (Microsoft) : processeurs 80x86 OS/ 2 (IBM) MacOS (Apple) : processeurs 68000 puis PowerPC UNIX = famille de SE : Versions payantes généralement spécialisées à un type de machine : SunOS/ Solaris (Sun) AIX (IBM) HP/ UX (HP) Versions libres : LINUX : 80x86, 68000, PowerPC, Sparc …
Présentation du BIOS BIOS (Basic Input Output System) : partie de l'OS du plus bas niveau opérations très primitives: lecture du clavier, affichage écran en mode texte, accès simplifié au lecteur de disquette et au disque dur, accès au ports série et parallèle. Le programme du BIOS se trouve en mémoire morte (ROM) une mémoire gardant son contenu lorsque l'on interrompt son alimentation électrique Chaque modèle de PC est vendu avec une version du BIOS adapté à sa configuration matérielle.
Fonctions du BIOS BIOS librairie de fonctions Chaque fonction effectue une tâche bien précise (par exemple afficher un caractère donné sur l'écran) L'appel de l'une de ces fonctions = appel système Fonctions du BIOS procédures appelées avec l'instruction CALL il a été prévu de pouvoir modifier le comportement du BIOS en cours d'utilisation (par exemple pour gérer un nouveau périphérique) Code du BIOS en ROM = non modifiable Le BIOS étant différent d'un ordinateur à l'autre, les adresses des fonctions changent...
Vecteurs d’interruption (1) Problème résolu par l'utilisation d'une table d'indirection = la table des vecteurs d'interruptions table est placée en RAM : contient les adresses (en ROM ou en RAM) des fonctions du BIOS implantée à partir de l'adresse 00000000H (première case mémoire) elle est initialisée par le BIOS lui même au moment du démarrage du PC (boot). Adresse contenu 0000 adresse de la première fonction du BIOS 0004 adresse de la deuxième fonction du BIOS ...
Vecteurs d’interruption Chaque élément de la table occupe 4 octets (adresse 32 bits). table à 256 éléments (1Ko). exemple : si l'on sait que la fonction du BIOS qui affiche un caractère est la 33ième, on va l'appeler en lisant la 33ième ligne de la table, puis en allant exécuter les instructions à l'adresse trouvée : Adresse contenu ... 0084H F1234560H (car 4x33 = 84H). La table des vecteurs d'interruptions contient des valeurs différentes pour chaque version de BIOS peut être modifiée pour pointer sur du code en mémoire principale, modifiant alors le BIOS existant.
Interruptions Unité de Traitement exécute séquentiellement les instructions ou effectue des sauts programmés (JMP, CALL) Il existe des situations où l ’U. T. est « déroutée » de sa tâche : Reset : signal envoyé au processeur pour un (re-) démarrage Exceptions (interruptions internes) : débordement de pile, dépassement de capacité, div /0, … Appels systèmes (int. logicielles) : appels du programme lui- même « int 21h » … Interruptions physiques (int. externes) : appels d’autres périphériques
Interruptions logicielles : INT n L'instruction INT n permet d'appeler la n-ième fonction de la table des vecteurs d'interruptions. n est un entier compris entre 0 et 255 (1 octet), car il y a 256 vecteurs d'interruptions dans la table (ex: Int 21h ) L'instruction INT n est semblable à l'instruction CALL sauf que l'adresse de destination est donnée par la table des vecteurs d'interruptions que les indicateurs sont automatiquement sauvegardés sur la pile. l’adresse de retour complète (32 bits) doit être empilée car le traitant d’interruption n’est pas nécessairement dans le même segment de code que le programme
Interruptions : déroulement Le déroulement de INT n se passe comme suit : sauvegarde les indicateurs du registre d'état sur la pile (les indicateurs sont regroupés dans un mot de 16 bits); sauvegarde CS et IP sur la pile; CS et IP sont chargés avec la valeur lue à l'adresse 4 n, n étant le paramètre de INT. L'exécution continue donc au début du traitant d'interruption.
Interruptions : fonctionnement Lorsque l’interruption est déclenchée, l ’U. T. doit exécuter un bout de programme précis : le traitant de l’interruption. l ’U. T. doit savoir où se trouve l ’adresse (CS: IP) du traitant numéro n Cette information est stockée en mémoire (0000: 0000 à 0000: 03FFh)
Appels système Le système DOS (Disk Operating System) repose sur le BIOS, il appelle les fonctions du BIOS pour interagir avec le matériel Les fonctions du DOS s'utilisent comme celles du BIOS, via des vecteurs d'interruptions fonctionnalités de plus haut niveau que le BIOS (entrées/sorties, ouverture de fichiers sur disque, etc.) Les fonctions du DOS s'appellent à l'aide du vecteur 21H La valeur du registre AH permet d'indiquer quelle est la fonction que l'on appelle : MOV AH, numero_fonction INT 21H fonction 4CH du DOS = terminer un programme et de revenir à l'interpréteur de commandes DOS : MOV AH, 4CH INT 21H
Fonctions du BIOS INT Fonction 0 Division par 0 appelé automatiquement lors de div. par 0 5 Copie d'écran 10H Écran gestion des modes vidéo 12H Taille mémoire 13H Gestion disque dur (initialiser, lire/écrire secteurs) 14H Interface série 16H Clavier (lire caractère, état du clavier)
Fonctions du DOS Numéro Fonction 01H Lecture caractère met le code ascii lu dans AL 02H Affiche caractère code ascii dans registre DL 09H Affiche chaîne de car DX=adresse début chaîne, terminée par '$' 0BH Lit état clavier met AL=1 si caractère, 0 sinon. Ce programme lit un caractère au clavier et l'affiche en majuscule : MOV AH, 01H ; code fonction DOS INT 21H ; attente et lecture d'un caractère AND AL, 11011111b ; passe en majuscule MOV DL, AL ; MOV AH, 02H ; code fonction affichage INT 21H ; affiche le caractère
Exemple Affichage d'un octet en binaire : afficher la valeur contenue dans un registre 8 bits (BL). L'idée est d'utiliser un masque BL AND 10000000 pour tester le bit de gauche, et de décaler BL à gauche pour parcourir ainsi tous les bits. mov BL, 10 ; on teste le prog avec BL=10 mov CX,8 ; compteur de boucle masque: Test BL, 10000000b JNZ bit1 bit0: Mov DL,"0" jmp affiche bit1: Mov DL,"1" affiche: mov AH,2 ; affichage int 21h SHL BL,1 Loop masque fin: mov ah,4Ch