GIF-1001
Etienne Tremblay
Ordinateurs, Structure et Applications
GIF-1001
Université Laval, Hiver 2012
Cours 8, Registres, Mémoire et Instructions Arithmétiques/Logiques
du 8086
Registres et drapeaux
Tiré du didacticiel de EMU8086
GIF-1001
Les registres
• AX: Registre accumulateur 16 bits ( composé de deux registres 8 bits, AH et AL).
• BX: Registre d'adresses de base 16 bits (composé de deux registres 8 bits, BH et BL).
• CX: Registre compteur 16 bits (composé de deux registres 8 bits, CH et CL).
• DX: Registre de données 16 bits (composé de deux registres 8 bits, DH et DL).
• SI: Registre d'index source 16 bits.
• DI: Registre d'index destination 16 bits.
• BP: Registre pointeur de base 16 bits.
• SP: Registre pointeur de pile 16 bits.
• IP: Instruction pointeur 16 bits.
Tiré du didacticiel de EMU8086
Les drapeaux
• Carry Flag (CF) – Ce flag est à 1 lorsqu’il y a une retenue (carry) dans une addition -ou un emprunt (borrow) lors d’un soustraction- sur le bit le plus significatif.
• Zero Flag (ZF) - Ce flag est à 1 lorsque le résultat est zéro.
• Sign Flag (SF) - Ce flag est à 1 lorsque le résultat est négatif.
• Overflow Flag (OF) - Ce flag est à 1 lorsqu'un débordement a lieu.
• Parity Flag (PF) - Ce flag est à 1 lorsque le résultat est un nombre pair de bits.
Même si le résultat est un Word (mot), uniquement les 8 bits de poids faible sont analysés !
• Auxiliary Flag (AF) - Ce flag est à 1 lorsqu'un débordement non signé a lieu sur les 4 bits de poids faible.
• Interrupt enable Flag (IF) - Lorsque ce flag est à 1, le processeur réagit aux interruptions des dispositifs externes.
• Direction Flag (DF) - Ce flag est utilisé par quelques instructions pour traiter les chaînes de données. Lorsque ce drapeau est placé à 0, la chaîne est traitée octet par octet en incrémentant, lorsque ce drapeau est placé à 1, la chaîne est traitée octet par octet en décrémentant.
Les drapeaux sont tous contenus dans un unique registre de status.
GIF-1001
Mémoire et registres segments (1)
• Le 8086 a 20 lignes d’adresses et peut donc accéder à une mémoire de 2^20 adresses, soit 1Mo ou FFFFh.
• Chaque case de mémoire contient 1 byte.
• Comme les registres n’ont que 16 bits, un registre seul ne peut qu’accéder à 64Ko de mémoire.
• Les registres segments permettent d’accéder à toutes les adresses de la mémoire.
• Il y a 4 segments: un segment de code (le programme), 2 segments de
données (les variables) et 1 segment pour la pile (voir plus loin).
• La convention Little Endian est utilisée pour stocker des mots de 2 bytes
ROM 256K
C0000h FFFFFh FFFF0h
BFFFFh
A0000h 9FFFFh
VIDEO RAM 128K
RAM 640K
00000h 003FFh Note: 64K = 2^(6+10) = FFFF+1
Segment de données 64K
Segment de données extra 64K Segment de code 64K
Pile 64K
Code pour reset
Table d'interruptions
DS*16
16DS + FFFFCS*16
ES*16 SS*16 F4000h
Code pour les interruptions
Info système (00400h à 004FFh)
Mémoire et registres segments (2)
• Les 4 registres segments sont: CS (Code Seg.), DS (Data Seg.), ES (Extra Data Seg.) et SS (Stack Seg.).
• Les registres de segment ont 16 bits. Leur valeur
multipliées par 16 (équivaut à ajouter un 0 en hex) donne la première adresse d’un segment.
• Le segment de code contient le programme, ceux de data, les données, et celui de Stack, la pile. Il est cependant
possible d’utiliser les registres de segments à d’autres fins (déconseillé).
• Les segments peuvent être superposés (overlap).
• À moins de modifier les registres segments à l’intérieur même d’un programme, la taille maximum d’un
programme est 4*64k = 256k. Un programme où tous les
registres segments ont la même valeur fait 64k (.com).
GIF-1001
Les registres segments et associations
• Chaque registre segment doit être associé à un ou plusieurs registres afin de former une adresse physique réelle. La table suivante donne ces associations:
• Une adresse physique est exprimée sous la forme aaaa:bbbb en hexadécimal où aaaa est le segment et bbbb est l’offset (ou adresse
virtuelle!?!). La valeur de l’adresse physique sur 20 bits est aaaa0h+bbbb ou encore aaaa*16+bbbb.
• Supposons par exemple que CS vaille 1111h et que IP vaille AAAAh.
Alors, l’adresse de l’instruction de programme pointée par IP (celle qui sera exécutée) est 11110+ 0AAAAh = 1BBBAh.
• Pour les instructions affectant la pile (PUSH, POP, CALL, RET, etc.), SS:SP est utilisé. SS:BP est l’adresse de base de la pile.
• DS:BX est utilisé avec l’instruction MOV (qui équivaut à une affectation) pour chercher des données en mémoire.
• DS:SI et ES:SI sont habituellement utilisés pour travailler sur des tableaux ou des chaînes de caractères.
Registre segment Registres associés
CS IP
SS SP et/ou BP
DS BX et/ou SI
ES DI
Les modes d’adressage (MOV)
• Un mode d’adressage est une instruction offerte par un microprocesseur afin de transférer de l’information d’un emplacement mémoire à un autre emplacement. C’est une opération d’affectation souvent représentée en
assembleur par l’instruction MOV.
• Pour le 8086, l’instruction MOV dst,src signifie mettre le contenu de src (la source) dans dst (la destination). On dit que dst et src qu’ils sont des opérandes.
• Src et dst peuvent être certains registres, des adresses (variables) ou des constantes (immédiate en anglais, dst ne peut pas être une constante!).
• Le 8086 supporte des transferts de bytes ou de mots (1
word = 2 bytes) dans certains cas. Src et dst doivent
toujours avoir la même taille.
GIF-1001
Les modes d’adressage (2)
MOV REG, mémoire Direct addressing mode, base adressing mode, etc.
MOV mémoire, REG
MOV REG, REG Register Mode MOV mémoire, immédiate
MOV REG, immédiate Immediate Mode
REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
mémoire : BYTE PTR [BX], WORD PTR [BX], [BX+SI+7], variable, etc.
immédiate : 5, -24, 3Fh, 10001101b, etc.
MOV SREG, mémoire MOV mémoire, SREG MOV REG, SREG MOV SREG, REG
SREG : DS, ES, SS, source seulement : CS.
REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
mémoire : b. [BX], w. [BX], [BX+SI+7], variable, etc.
Remarques:
- L'instruction MOV ne peut pas changer les valeurs des registres CS et IP.
- MOV mémoire, mémoire n’existe pas.
Variables
• Une variable est un nom donné à une adresse de mémoire. Il n’existe pas d’instruction pour créer ou manipuler des variables. Il n’existe que des instructions pour manipuler la mémoire.
• Les variables sont des créations du langage assembleur afin de faciliter la création d’un programme: Il est plus facile de retenir un nom qu’une adresse de mémoire!!!
• Avec les assembleurs de 8086, la syntaxe pour déclarer une variable est:
– nom DB valeur pour déclarer une variable d’un byte dont la valeur initiale est valeur et le nom est nom.
– nom DW valeur pour déclarer une variable d’un mot.
• L’instruction DB sert à un insérer un byte dans la mémoire du 8086.
L’adresse de ce byte est l’adresse de la variable. DW insère 2 bytes… Il est possible, si l’on connaît les opcodes et les opérandes des instructions du 8086 décrire un programme avec des DB!
• L’assembleur s’occupera de remplacer tous les noms des variables par les adresses correspondant à ces nom.
• L’instruction LEA permet d’aller chercher l’adresse d’une variable. OFFSET aussi, voir le didacticiel de EMU8086.
Note: Changer la valeur de DS peut créer de jolis problèmes avec les variables.
GIF-1001
Tableaux
• Les tableaux peuvent être vus comme des chaînes de variables.
Une chaîne texte est un exemple de tableau d'octets, chaque
caractère est présenté comme un élément de code ASCII (0 à 255).
Voici quelques exemples de définition d'un tableau : a DB 48h, 65h, 6Ch, 6Ch, 6Fh, 00h
b DB 'Hello', 0
b
est la copie exacte d'une rangée, lorsque le compilateur voit une chaîne entourée par des guillemets, il la convertit automatiquement en un ensemble d'octets.
• Si vous devez déclarer un grand tableau, vous pouvez utiliser l'opérateur DUP.
Par exemple : c DB 5 DUP(9)
La déclaration sans DUP :
c DB 9, 9, 9, 9, 9
Constantes
• La directive assembleur EQU permet de déclarer des constantes (comme un #define en C). Exemple: MyConst EQU 12h.
• Lors de l’assemblage, tous les MyConst de l’exemple ci-dessous seraient remplacés par 12h…
GIF-1001
Instructions arithmétiques et logiques, principe
• Les instructions arithmétiques et logiques sont des opération mathématiques (+, -, *, /) ou booléennes
(AND, XOR, NOT, ROL, ROR) opérée sur des bits. Les nombres sont exprimées en notation complément 2.
• Les instructions arithmétiques et logiques changent presque toujours les valeurs de certains drapeaux (en fonction de l’instruction).
• Le résultat de l’opération est habituellement placé dans le premier opérande: ADD A,B vaut A = A + B.
• Plusieurs registres ne peuvent être utilisés pour des
opérations arithmétiques et seuls AX,BX,CX et DX
peuvent être utilisés directement pour les opérations
avec des bytes.
ADD, SUB, CMP, AND, TEST, OR, XOR
2 opérandes:
REG, mémoire mémoire, REG REG, REG
mémoire, immédiat REG, immédiat
REG = AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
Ces instructions affectent les flags suivants : CF, ZF, SF, OF, PF, AF.
ADD - Ajoute le deuxième opérande au premier.
SUB - Soustrait le deuxième opérande au premier.
CMP – Compare les deux opérandes (soustraction) et change les drapeaux uniquement en fonction de la comparaison.
AND - Compare par un ET logique tous les bits des deux opérandes.
TEST - Idem à AND mais change les drapeaux uniquement.
OR - Effectue un OU logique entre tous les bits des deux opérandes.
XOR - Effectue un OU exclusif logique entre tous les bits des deux
GIF-1001
Exemple d’opérations sur des bits
• Supposons que l’on veille mettre le bit 3 (2^3) de AX à 0, mais laisser le reste du registre intact:
– AND AL, F7h
• Supposons que l’on veille mettre le bit 3 (2^3) de AX à 1, mais laisser le reste du registre intact:
– OR AL, 08h
MUL, IMUL, DIV, IDIV
• 1 seul opérande = REG ou mémoire
• REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
Les instructions MUL et IMUL affectent uniquement les flags CF et OF : lorsque le résultat est plus grand que la taille de l'opérande ces flags sont placés à 1, lorsque la taille de l'opérante est ajustée ces flags sont placés à 0.
Pour DIV et IDIV les flags ne sont pas définis.
• MUL - Multiplication non signée :
– byte : AX = AL * opérande.
– word : (DX AX) = AX * opérande.
• IMUL - Multiplication signée :
– byte : AX = AL * opérande.
– word: (DX AX) = AX * opérande.
• DIV - Division non signée :
– byte : AL = AX / opérande; AH = reste (modulo)…
– word : AX = (DX AX) / opérande; DX = reste (modulo)…
• IDIV - Division signée :
– byte : AL = AX / opérande; AH = reste (modulo)…
GIF-1001
Note sur les multiplications et divisions
• En base deux, les multiplications et les divisions par des multiples de 2 peuvent (devraient!!!) se faire avec RCL et RCR (Rotate Left/Right with Carry), SAL et SAR (arithmetic left/right shift), ou ROL et ROR (ROtate Left/Right).
• Schéma de RCL, RCR, SAL, SAR, ROL et ROR pour une rotation de 1 bit:
7 6 5 4 3 2 1 0 C
Carry Opérande 1 Initial
RCL
RCR 0 C 7 6 5 4 3 2 1 7 6 5 4 3 2 1 0 C
SAL
SAR 0 7 7 6 5 4 3 2 1 7 6 5 4 3 2 1 0 0
ROL
ROR 0 0 7 6 5 4 3 2 1 7 6 5 4 3 2 1 0 7
INC, DEC, NOT, NEG
• Un opérande = REG ou mémoire
•
REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP,SP.
Les instructions INC, DEC affectent les flags suivants :
ZF, SF, OF, PF, AF.L'instruction NOT n'affecte aucun flag.
L'instruction NEG affecte les flags suivants : CF, ZF, SF, OF, PF,
AF.•
INC– Ajoute 1 à l'opérande.
•
DEC– Soustrait 1 à l'opérande.
•
NOT- Inverse chaque bit de l'opérande.
•
NEG- Effectue un complément à 2 sur l'opérande négative. En fait, inverse chaque bit de l'opérande et lui ajoute 1.
Note: Si vous n’avez qu’un seul byte de 0 à 255, la meilleur façon
GIF-1001
Références et exercices
• Références pour tout l’assembleur
– Irv Englander: chapitre 12 (jusqu’à la page 351) et Annexe 2.
–
http://www.commentcamarche.net/asm/assembleur.php3–
http://www.ifrance.com/zarbi-os/DOCS/chap2.htm (très bonrésumé)
–
Didacticiel de EMU8086 (Pour débutants, mais bien fait)–
www.intel.com/design/intarch/datashts/24018708.pdf(datasheet
du 8086)–
William Stallings: chapitre 10 + 11.2• Exercices
– Lire le didacticiel de EMU8086
Annexe: Binaire de l’instruction MOV du 8086
Théorie :
• Le 8086 a un jeu d’instruction relativement simple (par rapport à d’autres jeux d’instructions). Il est capable d’effectuer toutes les
opérations de bases d’un microprocesseur (sur des entiers 16 bits ou 8 bits), mais il ne gère pas de nombres flottants, il ne peut contrôler qu’une quantité limitée de ressource (mémoires et I/Os) et sa vitesse d’exécution est plutôt lente.
• À la fin de la datasheet proposée sur le site web du cours (il y en a plusieurs disponibles sur internet!!!), vous retrouverez chaque instruction disponible pour le 8086. Ces instructions font habituellement 1 byte et elles sont habituellement simples à interpréter à partir du binaire. Toutefois, l’instruction MOV, la plus complexe, est difficile à interpréter selon les données disponibles. Voici donc un exemple de bits représentant cette instruction. Dans l’exemple, qui suit, le contenu de la mémoire à l’adresse 0102h est mis dans le registre BX.
• Instruction MOV BX,[0102h], écrite en binaire:
• 1000 10110001 1110 0000 00100000 0001b
• Premier byte (1000 1011): Selon la datasheet, l'opcode de l'instruction MOV, pour tranférer une donnée de la mémoire à un registre, ou vice versa, est 1000 10. Ensuite, vous avez les champs det w. Comme l'indique la dernière page de la datasheet, il faut mettre d (direction) à 1 pour envoyer vers le registre. Par ailleurs, mettre le champsw(word/mot sur 16bits ou variable sur 8bits) à 1 indique qu'il faut transférer 16 bits.
• Deuxième byte (00 011 110): Selon la datasheet, vous avez les champs MOD (00), REG (011) et r/m (110). Le champs MOD dit s'il faut faire un MOV de registre à registre ou de registre à mémoire. Il dit également s'il faut additionner les contenus de certains registres au déplacement (une adresse de mémoire est définie par un déplacement à l'intérieur d'un segment; l'instruction MOV peut être très
complexe: par exemple MOV AX, [BX + SI + 1234h]). Le champs r/m définit les registes entrant dans le calcul de l'adresse/déplacement.
Dans notre cas, MOD est 00 et r/m est 110 afin que le déplacement soit décrit par les deux bytes suivant en mémoire seulement (voir l'astérisque dans la datasheet: *except if mod = 00 and r/m = 110, then EA = disp-high;disp-low). REG est 011 pour indiquer que la destination du MOV est BX (voir la table pour REG à la dernière page de la datasheet).
• Troisième et quatrième byte (00000010 00000001): Ces deux bytes décrivent le déplacement (DISP follows 2nd byte of instruction (before data if required)). Comme on fonctionne en little endian, le byte le moins significatif du déplacement (0102h) est placé en mémoire le premier.