Laboratoire 7 - Révision
Note: généreusement contribué par Nicholas Cantin
Objectifs
- Vous faire réviser la matière des cours 1 à 7
- Vous familiariser avec la feuille d’aide mémoire pour les appels systèmes, les instructions et les codes ASCII importants.
- Vous faire travailler avec du code d’assembleur
note : Cet examen pratique ne peut pas toucher à tous les concepts. Prenez le temps de relire vos notes et de refaire les labos sur des concepts qui ont moins été compris.
conseil : Faites-vous une feuille qui contient une table de conversion rapide entre binaire-décimal-hexadécimal des nombres 1 à 16 pour éviter de perdre trop de temps à convertir chaque valeur à la main, surtout quand vous faites de l’arithmétique.
Question 1 :
Répondez aux questions suivantes (vrai/faux, QCM et très court développement)
i. Pour déterminer la taille maximale d’un nombre entier NON SIGNÉ sur n bits, il faut utiliser la formule suivante : 2^(n-1) - 1.
- vrai
- faux
ii. Je suis un caractère qui représente 4 bits.
- a) un word
- b) un code ASCII
- c) un octet
- d) un chiffre hexadécimal
iii. Que se passe-t-il lorsque le résultat d’une opération est hors domaine?
iv. Dans quel registre faut-il passer l’argument lorsqu’on utilise printInt ?
v. Quelle est l’utilité du registre a7?
vi. Vous circulez dans un tableau qui contient des caractères ASCII (.byte
). Vous voulez accéder à 6 éléments plus loin dans le tableau. Quelle valeur allez vous devoir additionner au registre contenant l’adresse du tableau?
- a) 6
- b) 12
- c) 24
- d) 48
vii. Encore avec un tableau contenant des caractères ASCII, quelle instruction devez-vous utiliser pour extraire le caractère de la case dans laquelle vous vous trouvez?
- a) lb
- b) lbu
- c) lw
- d) lwu
iix. slli
peut être utilisé pour multiplier la valeur d’un registre.
- vrai
- faux
ix. À quel bit doit-on se référer pour déterminer si un nombre est positif ou négatif
x. Une pseudoinstruction consiste d’une ou plusieurs vraies instructions machines.
- vrai
- faux
xi. On veut définir un tableau de 10 entiers 16 bits signés. Pour garantir que les loads et stores des éléments soient naturellement alignés, l’adresse du tableau devrait être un multiple de combien ?
xii. La taille des registres dépends de?
Question 2 :
Dans votre nouvel emploi, on vous demande de créer un programme qui permettra aux utilisateur de transformer des degrés Kelvin en degrés Celsius. Lorsqu’un utilisateur rentre le nombre 0
, on lui retourne -273. Considérant que votre outil utilise des registres de 16 bits, répondez aux questions suivantes en laissant des traces de votre démarche :
a) Quelle est la représentation en binaire du registre contenant “-273” si on travaille en complément de deux? Écrivez le résultat sur 16 bits.
b) Quelle est sa représentation sous format hexadécimal (toujours sur 16 bits)?
c) Un bug dans le système est survenu et votre programme à imprimé le résultat en binaire. Cependant, il s’agissait d’une donnée très importante et vous devez le convertir en décimal pour vos collègues avant de corriger ce bug. Voici le nombre en question : 0000 0001 0111 0011
d) Vous installez une nouvelle fonctionnalité qui permet d’additionner des registres dans votre programme. Pour le tester, vous décidez d’additionner un registre contenant la valeur 0xCAFE et un autre registre contenant la valeur 0xA15. Quelle est la valeur obtenue en hexadécimale (toujours sur 16 bits) ?
Question 3 :
Voici un programme mystère :
indice : regardez les codes ascii importants
#Appels système utilisées
.eqv printInt, 1
.eqv exit, 10
li s0,0
loop:
li a7,12
ecall
li t0,33 #33 = ! dans la table ASCII
beq a0,t0,fin
li t0,65
blt a0,t0,loop
li t0,90
bgt a0,t0,loop
addi s0,s0,1
j loop
fin:
li a7,printInt
mv a0,s0
ecall
li a7,exit
li a0,0
ecall
a) Décrivez ce que ce programme fait en quelques phrases.
b) Qu’allons nous obtenir si on entre dans ce programme “BONJOUR tout le monde!” ?
Question 4 :
Un problème survient dans votre ordinateur et vous perdez votre dernière heure de travail. Des morceaux de prochainElement
et de finProg
ont été effacés. Voici ce qu’il vous reste comme code :
#Appels système utilisées
.eqv printInt, 1
.eqv exit, 10
.data
# Tableau de 10 nombres (64bits signés)
tab: .dword 10, 10, -6, 20, 1, 1, 8, 800, -800, -2
.eqv tablen, 10 # Taille du tableau (en nombre d'éléments)
.text
la s1, tab # Adresse de l'élément courant
li s2, tablen # Nombre d'éléments restants à traiter
ld s0, 0(s1) # on initialise avec le premier élément
loop:
ld s3, 0(s1) # Valeur de l'élément courant
blt s0, s3, prochainElement
mv s0, s3
prochainElement:
# À remplir
bgtz s2, loop #après les 10 éléments circulés, on ne rentre plus dans cette condition, on continue dans finProg
finProg:
# À remplir
a) Expliquez ce que fait ce programme (pas besoin des fonctions effacées pour répondre).
b) Qu’est-ce que ce programme retourne si l’on prends les données présentes dans tab
?
c) Écrivez les fonctions prochainElement
et finProg
directement dans le code. Vous devriez avoir 7 nouvelles lignes d’instructions.
d) Vous souhaitez passer ceci dans votre programme : tab2: .word 11, 5, -19, 24, 30, -30, 90, -150, 400, -12
.
Cependant, votre programme se termine avec des erreurs. Pourquoi? Comment peut-on corriger cette erreur?
Question 5 :
Soit le morceau de programme suivant exécuté sur une architecture RISC-V 64 bits. Sachant que l’étiquette foo est associée à l’adresse 0x10010000, indiquez quel est le contenu (hexadécimal) final des registres demandés. Voici le code en question :
.data
.eqv bar, 0x95
foo: .byte bar, 0x87, 0x10, 0x01
.text
la s0, foo
lw s1, 0(s0)
li s2, bar
lb s3, 0(s0)
ebreak # Fait une pause dans l'éxécution
Lors du ebreak, quelle valeur a….
- Le registre s0?
- Le registre s1?
- Le registre s2?
- Le registre s3?
Question 6 :
En faisant référence à la feuille aide mémoire des instructions RARS :
a) Transformez l’instruction assembleur slli s0,s8,12
en code machine (donnez la valeur hexadécimale).
b) Quelle instruction assembleur correspond à l’instruction machine de valeur 0x02948433
?
Question 7 (extra) :
On travaille avec un programme qui change l’intensité d’une des couleurs présente dans un registre de 32 bits ayant le format « 0xAARRGGBB » qui correspond à un “Hex color code”. A = Alpha, R = Red, G =Green et B = Blue. Un exemple pour vous aider à comprendre serait la valeur 0x0000FF00
où la couleur verte a une valeur de 255 (le maximum) et alpha, rouge et bleu ont 0 (le minimum). Pour vous faciliter la vie, on vous demander de seulement travailler avec la couleur rouge et une partie du code est déjà présente.
Vous allez devoir implémenter deux fonctions. Voici le code qu’on vous donne :
.eqv printHex,34
.eqv exit,10
li s1,0xAABBCCDD #Registre que l'on veut modifier (ARGB = 0xAARRGGBB), fixe dans ce contexte
userInput:
li a7,5
ecall
mv s0,a0 #saisie de l'utilisateur (peut être négatif)
isolerCouleurRouge:
#isoler rouge (RR) dans s2
#décaler le masque à droite du registre pour
#lui faire subir le addi
addi s2,s2,s0
verifierMax:
li t0,255 #valeur max possible pour une couleur
ble s2,t0,verifierMin #si s2 > 255 on mets la valeur 255 dans s2
li s2,255
verifierMin:
li t0,0
bge s2,t0,replacerCouleur #valeur min possible pour une couleur
li s2,0 #si s2 < 0 on mets la valeur 0 dans s2
replacerCouleur:
#aligner le registre s2 avec la couleur rouge
#vous devriez avoir 0x00RR0000 et lui appliquer
#un masque pour le réintégrer dans s1 sans
#influencer les autres bits présents
finProg:
mv a0,s2
li a7,printHex #print hexadecimal value (appel système de RARS)
ecall
li a0,0 #fermer le prog
li a7,exit
ecall
a) Complétez les fonctions isolerCouleurRouge
et replacerCouleur
.
b) S’il n’y avait pas de gestion d’erreur (dépassement min et max), qu’arriverait-il au registre s1
lorsqu’on lui ajoute la couleur rouge modifié (On sous-entends ici qu’on dépasse les bornes, soi une valeur plus petite que 0 ou plus grande que 255)?
Solutionnaire
Dans une page à part