GIF-1001, 10 mars 2010 Nom/Matricule : _________________________
Examen 1
Cet examen vaut 40% de la note totale du cours. Les questions seront corrigées sur un total de 40 points.
La valeur de chaque question est indiquée avec la question. Une calculatrice scientifique peut être utilisée.
Cependant, aucune documentation, autre que les annexes, n’est permise. Vous pouvez répondre aux questions directement sur ce questionnaire et/ou dans le cahier bleu mis à votre disposition.
Q1 (1+2+1+1+3+4 points) : Vous avez le système microprocesseur suivant :
Microprocesseur -16 registres de 8 bits pour les opérations d'ALU (R0 à R15) - Registre d'Instruction (IR) sur 16 bits
0x00 0x81 0x44 0x420x44 0x80 0x44 0x21 Données
Lecture Écriture Activation
0x81 0x40 0x11 0x820x08 0x40 0x40 0x81 Données
Lecture Écriture Adresse
Adresse Activation
Mémoire 1 Mémoire 2
8 8
A2 A0 A3 A4
Octet 0 de la mémoire
Dans ce système, le microprocesseur exécute des instructions dont le format est décrit en annexe B. Le microprocesseur a 16 registres tout usage identifiés par R0 à R15 dans le texte qui suit. Par ailleurs, l’opcode de toutes les instructions est à l’adresse la plus basse, les paramètres étant à l’adresse la plus haute.
Ai) Combien d’instructions maximum peuvent être dans un programme supporté par ce microprocesseur (si toutes les adresses indiquaient une cellule unique de mémoire)?
- Le microprocesseur a 5 lignes d’adresse. Donc, il peut adresser 2^5 = 32 adresses de mémoire.
- Par ailleurs, selon l’annexe B et selon la taille du registre IR, tous les instructions ont une taille de deux octets.
- Puisque le bus de données a 8 bits, il y a obligatoirement 1 octet par adresse.
Réponse: instructions
n instructio
octets adresse
octet adresses
16 2
1
* 25
=
Aii) Pour toutes les adresses du microprocesseur, dites quelle mémoire est accédée.
A3 et A4 seulement déterminent quelle mémoire sera active. Ces broches sont reliées aux broches d’activation de la mémoire selon la table de vérité suivante :
A4 A3 A2 A1 A0 Activation
Memoire1
Activation Memoire2
0 0 X X X 0 1
0 1 X X X 1 0
1 0 X X X 0 0
1 1 X X X 1 0
Les adresses de 0 à 7 (00000b à 00111b) activeront la mémoire 2.
Les adresses de 8 à 15 (00000b à 00111b) activeront la mémoire 1.
Les adresses de 16 à 23 (00000b à 00111b) n’activeront aucune mémoire.
Les adresses de 24 à 31 (00000b à 00111b) activeront la mémoire 1.
Il faut noter que qu’utiliser l’adresse 8 ou l’adresse 24 indiquera la même case de mémoire, c’est-à-dire la case de mémoire 0 de la mémoire 1 (qui contient 0x21 selon la figure).
Mi) Combien d’accès mémoire seront nécessaire pour lire et exécuter l’instruction MOV R0, R1?
Toutes les instructions sont codées sur 2 octets.
Le bus de donnée permet de véhiculer 1 octet à la fois seulement (8 bits) Il faudra donc accéder 2 fois à la mémoire pour lire l’instruction.
L’instruction MOV R0, R1 transfère le contenu d’un registre à un autre. Comme les registres sont dans le microprocesseur, il n’y a pas d’accès mémoire lors de l’exécution de l’instruction.
Mii) En fonction des valeurs de l’annexe B, comment serait encodée l’instruction MOV R0, Mavar, sachant que Mavar est une variable en mémoire? Choisissez l’adresse de MaVar.
Chaque instruction est constituée d’un opcode qui décrit ce que fait l’instruction (son action) et de paramètres qui décrivent les variables/données visées par l’action. Selon l’annexe B, toutes les instructions du microprocesseur ont 2 octets, le premier étant l’opcode et le second étant les paramètres.
Le paramètre le plus commun d’une instruction de microprocesseur est un numéro de registre. Comme le microprocesseur a 16 registres, il faut 4 bits pour identifier un
registre. Donc, avec 8 bits pour les paramètres, il est possible de désigner deux registres.
Par exemple, l’instruction 0x2146 a pour opcode 0x21 et comme paramètres 4 et 6. 0x21 indique une addition, 4 désigne R4 et 6 désigne R6 de telle sorte que 0x2146 serait, en assembleur, ADD R4,R6.
Un autre paramètre très commun d’une instruction de microprocesseur est une adresse de mémoire. Comme les adresses du microprocesseur sont sur 5 bits, ce paramètre devrait avoir 5 bits. Or, désigner une adresse (sur 5 bits) et un registre (sur 4 bits) à l’intérieur d’un champs de paramètres sur 8 bits ne fonctionnerait pas. Pour cette raison certaines instructions utilisant une adresse ont des opcodes doublés : un opcode permet d’accéder aux adresses de 0 à 15 (sur 4 bits) et l’autre permet d’accéder aux adresses de 16 à 31…
Donc l’adresse de MaVar déterminera non seulement un paramètre, mais aussi l’opcode.
Si je choisis 0x0F par exemple, j’aurai :
MOV R0,Mavar ===0x810F; 0x81 est Mov (adresse de 0 à F), 0 est R0 et F est l’adresse de MaVar.
Si je choisis l’adresse de Mavar = 0x12 par exemple, j’aurai :
MOV R0,Mavar ===0x8202; 0x82 est Mov (adresse de 10 à 1F), 0 est R0 et 2 est l’adresse de MaVar (à laquelle 0x10 est ajoutée en raison de l’opcode).
Miii) Supposons que l’adresse de la variable Mavar est 0x12 et que Mavar vaut 0x34.
Supposons aussi que l’instruction MOV R0, Mavar soit à l’adresse 0x08. Dites quelle séquence de valeurs apparaîtra sur les bus d’adresse, de données et de contrôle du système lorsque l’instruction sera lue, puis exécutée.
La lecture de l’instruction se fait en 2 étapes (2 accès à la mémoire) :
1a- Le microprocesseur met l’adresse de l’instruction (0x08) sur le bus d’adresse 1b- Le microprocesseur active LECTURE.
1c- Le microprocesseur lit la valeur 0x82 sur le bus de donnée, c’est-à-dire l’opcode de MOV R0, MaVar (voir Mii)
2a- Le microprocesseur met l’adresse de l’instruction (0x09) sur le bus d’adresse pour lire le restant de l’instruction
2b- Le microprocesseur active LECTURE.
2c- Le microprocesseur lit la valeur 0x02 sur le bus de donnée, c’est-à-dire les paramètres de l’instruction MOV R0, MaVar (voir Mii)
L’exécution de l’instruction se fait avec une lecture de la mémoire
3a- Le microprocesseur met l’adresse de la variable (0x12) sur le bus d’adresse 3b- Le microprocesseur active LECTURE.
2c- Le microprocesseur lit la valeur 0x34 sur le bus de donnée, c’est-à-dire la valeur de Mavar
Oi) Si la valeur initiale du compteur de programme (PC ou IP pour le 8086) est 0, dites que vaudront R4 et PC après l’exécution de trois instructions.
L’adresse 0 désigne l’octet 0 de la mémoire 2.
La première instruction à l’adresse 0 est 0x8140. Selon l’annexe B, cette instruction est MOV R4, [0]. Donc, R4 deviendra égal à 0x81. Le PC, quant à lui, sera incrémenté de deux parce qu’il y a deux octets par instruction.
La deuxième instruction à l’adresse 2 est 0x4008. Selon l’annexe B, cette instruction est JMP 0x08, soit un saut à l’addresse 8. Cette instruction ne change pas R4, mais PC devient 0x08.
La troisième instruction à l’adresse 8 est 0x2144. Selon l’annexe B, cette instruction est ADD R4,R4. R4 deviendra 0x81+0x81 = 0x102, soit 0x02 parce que le registre est sur 8 bits seulement (overflow !). En ce qui concerne PC, il sera incrémenté d’une instruction et deviendra 0x08 + 2 = 0x0A.
Q2 (10 points) : Le Binary Coded Decimal (BCD) est une façon de représenter les entiers en binaire. Avec le BCD, quatre bits sont utilisés pour représenter des nombres de 0 à 9 et six valeurs possibles des quatre bits (de 10 à 15) ne sont pas utilisées. Par
exemple, pour coder le nombre 2539d en BCD, vous retrouverez 0010 0101 0011 1001b en binaire.
Écrivez une fonction en assembleur qui additionne deux octets codés en BCD (un octet en BCD vaut de 0 à 99) et retourne la somme en BCD. Par exemple, votre fonction doit retourner 0x97 lorsque la fonction additionne 0x38 et 0x59. Considérez les éléments suivants :
- Les nombres à additionner sont dans AH et BH avant l’appel de la fonction - Le résultat de l’addition doit être dans CH.
- Le drapeau C doit être 1 lorsque le résultat de l’addition est supérieur à 0x99.
- À l’exception de CH, tous les registres doivent avoir la même valeur avant et après l’appel de la fonction (fonction propre)
- Habituellement, l’addition en BCD se fait par nibble (groupes de 4 digits). On additionne 6 si le résultat de l’addition est supérieur à 9.
- Considérez que l’instruction AAA n’existe pas.
- L’annexe A contient une liste d’instructions du 8086 qui peut vous aider.
- Le code suivant pourrait appeler votre fonction : MOV AH, NombreBCD1
MOV BH, NombreBCD2 Call AddOctetBCD MOV Resultat, CH
;Dans le code qui suit, AH contiendra toujours la somme des nibbles
;Dans le code qui suit, AL sera utilisé pour tester
;si les nibbles de AH (de la somme) sont plus grands que 9
;Le nibble LSB est traité en premier pour tenir compte d’une retenue
;entre les deux nibbles AddOctetBCD PROC
PUSH AX ;Sauvegarde AX sur la pile ADD AH,BH ;Effectue l’addition
MOV AL,AH ;Entrepose le résultat de l’addition dans AL AND AL,0x0F ;Garde le nibble LSB de la somme
CMP AL,0x09 ;Vérifie si la somme des nibbles LSB est > 9 JNG TraiteNibbleMSB
ADD AH,6 ;Le nibble LSB est > 9, additionne 6 TraiteNibbleMSB :
;Le nibble LSB est maintenant codé en BCD dans AH
;Il faut s’assurer que le nibble MSB est < 9
MOV AL,AH ;Entrepose le résultat de l’addition dans AL AND AL,0xF0
CMP AL,0x90 ;Vérifie si la somme des nibbles MSB est > 9 JNG GereCarry
ADD AH,0x60
;STC ;N’est pas requis parce qu’ajouter 6 créera une retenue…
JMP Fin GereCarry :
CLC Fin :
MOV CH,AH ;CH doit contenir la valeur calculée…
POP AX ;Récupère AX RET
AddOctetBCD ENDP
Q3 (5 points) : La valeur ASCII de ‘0’ est 0x30. Celle de ‘9’ est 0x39, de telle sorte que la valeur ASCII d’un nombre X entre 0 et 9 est X + 0x30. Dans l’exemple qui suit, le nombre représenté en ASCII dans AL est converti en décimal dans CL (CL = AL – 0x30) :
main:
PUSH AX
CALL ConvertirNbreASCIIenDecimal POP CX
ConvertirNbreASCIIenDecimal PROC PUSH BP
PUSH BX MOV BP, SP MOV BX, [BP + 6]
SUB BX, 0x30 MOV [BP + 6],BX POP BX
POP BP RET
ConvertirNbreASCIIenDecimal ENDP
Sachant que lors d’un empilement dans le 8086, SP est décrémenté de 2 puis la valeur empilée est mise sur la pile, illustrez l’évolution de la pile lors de l’exécution des instructions commençant à l’étiquette main. Une image vaut mille mots, mais plusieurs images, c’est encore mieux!
Après CALL ConvertirNbreASCIIenDecimal pile sera :
Valeur initiale de AX = Nombre à convertir SP –> Adresse de retour (adresse de POP CX) Après PUSH BX, la pile sera :
Valeur initiale de AX
Adresse de retour (adresse de POP CX) Valeur initiale de BP
SP –> Valeur initiale de BX
L’instruction MOV BX, [BP + 6] met le résultat de la conversion sur la pile :
Valeur initiale de AX – 0x30
Adresse de retour (adresse de POP CX) Valeur initiale de BP
SP –> Valeur initiale de BX
POP BX, POP BP, RET et POP CX dépilent des valeurs jusqu’à ce que la pile devienne :
SP –>
Valeur initiale de AX – 0x30
Adresse de retour (adresse de POP CX) Valeur initiale de BP
Valeur initiale de BX
Q4 (10 points) : Indiquez si les énoncés suivant sont vrai ou faux. Une bonne réponse vaut 1 point, une mauvaise réponse vaut -0.5 points et pas de réponse vaut 0.
# Énoncé V/F
A La valeur zéro peut être représentée en ASCII avec un byte ne valant pas zéro, en décimal sur deux bytes valant zéro et en fraction sur quatre bytes.
V B L’addition ou la soustraction de nombres représentés en notation complément 2
s’effectue toujours de la même manière, peu importe le signe des nombres.
V C Le compilateur remplace toutes les étiquettes (JMP MonEtiquette) et tous les
noms de fonction (CALL Mafonction) par des valeurs indiquant les adresses des étiquettes et des fonctions lorsqu’il génère le code binaire.
V
D C’est grâce à son nom qu’un microprocesseur trouve une variable. En effet, lorsqu’il doit lire ou écrire une variable, le microprocesseur cherche son mon dans la mémoire pour savoir son emplacement.
F
E Lorsque le microprocesseur ne trouve pas un registre dans sa mémoire interne,
il le cherche d’abord dans la cache L1. F
F Un disque dur tourne à vitesse angulaire constante afin d’assurer un taux de transfert de données constant, les données en périphérie étant moins denses.
V G Un CD ou DVD réinscriptible contient un alliage spécial dont les propriétés
optiques changent en fonction de la vitesse de refroidissement de l’alliage. V H L’assembleur remplace tous les mots d’un fichier texte en instructions binaires
pour le microprocesseur. Il faut donc un programme en assembleur pour chaque jeu d’instruction.
F
I Dans une architecture Von Neumann, que l'on retrouve dans les ordinateurs modernes, les données et instructions sont séparées sur des mémoires différentes.
F
J Le BIOS, en mémoire non-volatile, contient les premières instructions exécutées par le microprocesseur. Ces instructions testent l’ordinateur et chargent le système d’exploitation en accédant aux périphériques de base.
V
Q5 (3 points) : Pour les trois questions suivantes, choisissez uniquement le meilleur choix de réponse.
A) Généralement, lors d’une interruption, un microprocesseur : i. Termine l’instruction en cours
ii. Sauvegarde l’adresse de la prochaine instruction sur la pile iii. Trouve l’adresse d’une routine pour traiter l’interruption iv. Effectue un saut à une routine pour traiter l’interruption
v. Exécute une fonction spéciale codée à l’intérieur du microprocesseur vi. Toutes ces réponses, dans l’ordre, de i à iii
vii. Toutes ces réponses, dans l’ordre, de i à iv viii. Toutes ces réponses, dans l’ordre, de i à v
B) Habituellement, l’adresse de la routine servant à traiter/servir une interruption…
i. … est prédéterminée dans le microprocesseur.
ii. … est déterminée par une table en mémoire ROM.
iii. … est déterminée par une table en mémoire RAM.
iv. … est calculée en fonction de la météo.
C) Habituellement, lorsqu’un périphérique veut indiquer un évènement :
i. Il active une ligne spéciale d’interruption et attend indéfiniment que le microprocesseur traite l’interruption.
ii. Il prend le contrôle du bus de donnée et indique au microprocesseur qu’il y a une interruption.
iii. Il active une ligne spéciale d’interruption, puis il prend le contrôle du bus de donnée pour donner plus d’information au microprocesseur sur
l’interruption.
iv. Il écrit un octet de statut spécial à l’intérieur de la mémoire pour indiquer l’interruption
v. Aucune de ces réponses.
QBonus (2 points bonus) : Mathématiquement, effectuer c = a + (-b) revient à effectuer c = a – b. Cependant, effectuer c = a + (-b) n’a pas le même effet qu’effectuer c = a –b sur les drapeaux de l’ALU. Quel(s) drapeau(x) rend cette affirmation vraie? Illustrez à l’aide d’un exemple.
Le drapeau Carry rend cette affirmation vraie. Dans le cas d’une addition, ce drapeau indique une retenue alors qu’il indique un emprunt lors d’une soustraction.
Par exemple :
-1 + 1 donne une retenue alors que -1 – (-1) ne donne pas d’emprunt : 1111 1111 (-1) 1111 1111 (-1) + 0000 0001 (1) - 1111 1111 (-1)
1 0000 0000 (0, avec retenue) 0000 0000 (0, pas d’emprunt)
Annexe A : Liste non exhaustive des instructions du 8086 Instruction Description
ADD a,b Effectue a = a+b.
AND a,b Effectue a = a ET b, où ET est un ET logique.
CALL proc Appelle la procédure proc et empile l’emplacement de retour.
CLC Met à 0 le drapeau de retenue (carry).
CMP a,b Effectue a-b, a et b sont inchangés.
DEC a Décrémente a.
DIV mot Effectue AX = DXAX/mot, non signé, le résultat est tronqué (arrondi inférieur).
IDIV mot Effectue AX = DXAX/mot, signé, le résultat est tronqué (arrondi inférieur).
IMUL mot Effectue DXAX = AX*mot, signé.
IN dst, port Met la valeur lue sur le port de I/O port dans dst.
INC a Incrémente a.
INT a Appelle la routine de service d’interruption a. Empile les drapeaux et l’emplacement de retour.
IRET Retourne d’une int. en dépilant l’emplacement de retour et les drapeaux.
JC label Saute à l’instruction désignée par label si le drapeau Carry est 1.
JMP label Saute à label. La prochaine instruction exécutée est désignée par label.
JNC label Saute à l’instruction désignée par label si le drapeau Carry est 0.
JNZ label Saute à l’instruction désignée par label si le drapeau Zéro est 0.
JNS label Saute à l’instruction désignée par label si le drapeau Signe est 0.
JZ label Saute à l’instruction désignée par label si le drapeau Zéro est 1.
JS label Saute à l’instruction désignée par label si le drapeau Signe est 1.
LEA dst,var Met l’adresse de la variable var dans dst.
MOV dst,src Met le contenu de src dans dst. Ne change pas les drapeaux.
MUL octet Effectue AX = AL*octet, non signé.
NEG a Inverse tous les bits de a, puis ajoute 1.
NOT a Inverse tous les bits de a.
OR a,b Effectue a = a OU b, où OU est un OU logique.
OUT port, src Met la valeur de src sur le port de I/O port.
POP mot Dépile un mot. Ne change pas les drapeaux.
POPF Dépile les drapeaux.
PUSH mot Empile un mot. Ne change pas les drapeaux.
PUSHF Empile les drapeaux.
RET et RETF Retourne d’une procédure en dépilant l’emplacement de retour. RET dépile IP. RETF dépile IP puis CS.
RCL a,b Fait une rotation de b bits vers la gauche. La rotation inclut le bit de Carry.
RCR a,b Fait une rotation de b bits vers la droite. La rotation inclut le bit de Carry.
SAL a,b Décale tous les bits de a vers la gauche d’un nombre de bits égal à b. Des zéros sont mis à droite. Carry prend la valeur du bit disparu.
SAR a,b Décale tous les bits de a vers la droite d’un nombre de bits égal à b. Le bit le plus significatif de a est mis à gauche. Carry prend la valeur du bit disparu.
STC Met à 1 le drapeau de Carry SUB a,b Effectue a = a-b.
TEST a,b Effectue a ET b, où ET est un ET logique.
XOR a,b Effectue a = a XOR b, où XOR est un OU eXclusif.
Annexe B : Format des instructions du microprocesseur de la question 1
Instruction Paramètres Description
ADD Reg/Reg Opcode X Y
Opcode = 21h 8 bits 4 bits 4 bits RegistreX = RegistreX + RegistreY
JMP dest Opcode Dest
Opcode = 40h 8 bits 8 bits L'adresse de la prochaine instruction exécutée est Dest
MOV Reg/Reg Opcode X Y
Opcode = 80h 8 bits 4 bits 4 bits RegistreX = RegistreY
MOV Reg/LMem Opcode X Adr
Opcode = 81h 8 bits 4 bits 4 bits RegistreX = Memoire à l'adresse Adr
MOV Reg/UMem Opcode X Adr
Opcode = 82h 8 bits 4 bits 4 bits RegistreX = Memoire à l'adresse Adr + 16
MOV Reg/LCte Opcode X Cte
Opcode = C0h 8 bits 4 bits 4 bits RegistreX = (RegistreX & 0x0F) + Cte
Les 4 derniers bits du registre = Cte
MOV Reg/UCte Opcode X Cte
Opcode = C1h 8 bits 4 bits 4 bits RegistreX = (RegistreX & 0xF0) + Cte*16
Les 4 premiers bits du registre = Cte