TD : les instructions
1. Les opérations du matériel
1.1. Exercice
Quel est le code assembleur MIPS compilé pour l'expressions C ci-dessous ?
f=(g+h)-(i+j);
Les variables f, g, h, i et j peuvent être assignées aux registres $16 à $20.
(C’est au compilateur que revient cette tâche délicate.)
add $8,$17,$18 #Registre $8 contient g+h
add $9,$19,$20 #Registre $9 contient i+j
sub $16,$8,$9 # f reçoit $8-$9, ou (g+h)-(i+j)
2. Les opérandes du matériel
2.1. Exercice
Quel est le code assembleur MIPS pour l'expression C ci-dessous ?
T[i]=h+T[i] ;
T est un tableau d’entiers
On suppose que les variables g et h sont dans $17 et $18,
$19 contienne la valeur i, et que le tableau débute à l’adresse Tstart
L'expression d'affectation C devient
muli $19,$19,4 #i=i*4
lw $8,Tstart($19) #reg temporaire $8 reçoit T[i]
add $8,$18,$8 #reg temporaire $8 reçoit h+T[i]
sw $8,Tstart($19) #on recopie h+T[i]dans T[i]
3. Des instructions pour prendre des décisions
3.1. Exercice
Traduire en langage MIPS assembleur l'expression C suivante.
if (i==j)
f=g+h;
else
f=g-h;
si f,g,h,i et j correspondent aux registres $16 à $20
bne $19,$20,Else #aller en Else si i≠j
add $16,$17,$18 #f=g+h (sauté si i≠j)
j Exit #aller en Exit (jump)
Les instructions 1
Else: sub $16,$17,$18 #f=g-h (sauté si i=j)
Exit:
3.2. Exercice
Traduire l'expression C suivante en langage assembleur MIPS.
While (stock[i]==k)
i=i+j;
si i, j et k correspondent aux registres $19 à $21, le tableau stock débute à Sstart et le registre $10
contient la valeur 4.
loop : mult $9,$19,$10 #reg temporaire $9=i*4
lw $8,Sstart($9) #reg temporaire $8=stock[i]
bne $8,$21,Exit #aller en Exit si stock[i]≠k
add $19,$19,$20 #i=i+j
j Loop #aller en Loop
Exit:
4. La représentation des instructions dans l'ordinateur
4.1. Exercice
Quel est le code machine MIPS pour ces trois instructions ?
lw $8,Tstart($19) #reg temporaire $8 reçoit T[i]
add $8,$18,$8 #reg temporaire $8 reçoit h+T[i]
sw $8,Tstart($19) #on recopie h+T[i]dans T[i]
Représentons les instructions avec les nombres décimaux.
op rs rt rd decval adresse/fonct
35 19 8 1200
0 18 8 8 0 32
43 19 8 1200
op Rs rt rd decval adresse/fonct
8000 100011 10011 010000 0000 0100 1011 0000
8004 000000 10010 01000 01000 00000 100000
8008 101011 10011 01000 0000 0100 1011 0000
4.2. Exercice
Donner le code machine pour le code assembleur suivant
loop : mult $9,$19,$10 #reg temporaire $9=i*4
lw $8,Sstart($9) #reg temporaire $8=stock[i]
bne $8,$21,Exit #aller en Exit si stock[i]≠k
Les instructions 2
add $19,$19,$20 #i=i+j
j Loop #aller en Loop
Exit:
Les instructions assemblées et leurs adresses
80000 0 19 10 9 0 24
80004 35 9 8 1000
80008 5 8 21 8
80012 0 19 20 19 0 32
80016 2 80000
80020
5. Un exemple complet
Rappels
Pour traduire du C en assembleur :
- Allouer des registres aux variables du programme.
- Produire du code pour le corps de la procédure.
- Préserver les registres à travers l’appel de la procédure
Convention MIPS :
pour le passage de paramètres sont utilisés $4 à $7
5.1. Exercice
Donner le code pour la procédure suivante
change(int v[], int k){
int temp;
temp = v[k];
v[k]=v[k+1];
v[k+1]=temp;
}
Les paramètres v et k sont alloués à $4 et $5,une variable temp en $15 et $2 contient la base du
tableau
NB : les adresses de mots contigus différent de 4 et non de 1
Le corps de la procédure modifie les registres $2, $15 et $16
addi $29,$29,-12 #on ajuste la tête de pile
sw $2,0($29) #range $2 au sommet
sw $15,4($29) #range $15 au sommet
sw $16,8($29) #range $16 au sommet
muli $2,$5,4 #reg $2=k*4
add $2,$4,$2 #reg $2=v+(k*4)
#reg $2 a l’adresse de v[k]
lw $15,0($2) #reg $15 (temp)=v[k]
lw $16,4($2) #reg $16=v[k+1] ; fait référence à
#l’élément suivant de v
sw $16,0($2) #v[k]=registre $16
sw $15,4($2) #v[k+1]=registre $15 (temp)
Les instructions 3
lw $2,0($29) #restitue $2 du sommet
lw $15,4($29) #restitue $15 du sommet
lw $16,8($29) #restitue $16 du sommet
addi $29,$29,12 # restitue la tête de pile
jr $31 # retour à la procédure appelante
5.2. donner le code
For (i=0; i<1000 ; i++)
C[i]=A[i]+B[i];
Supposons que les adresses des variables soient :
24000-27996 vecteur A
28000-31996 vecteur B
32000-35996 vecteur C
36000 constante 0
36004 constante 3996
8000 lw $1,36000($0) *charger 0 dans r1
8004 lw $2,36004($0) *charger 3996 dans r2
8008 lw $3,24000($1) *charger A[i] dans r3
8012 lw $4,28000($1) *charger B[i] dans r4
8016 add $3,$3,$4 *ajouter [r4] à [r3]
8020 sw $3,32000($1) *ranger [r3] dans C[i]
8024 beq $1,$2,8036 *si [r1]=[r2] sauter en 8036
8028 addi $1,$1,4 *incrémenter r1
8032 j 8008 * sauter en 8008
8036
5.3. exercice
Voici un programme assembleur.
1 Add $19,$0,$0
2 Tstfor1: Slt $8,$19,$20 # $8=0 si $19>=$20
3 Beq $8,$0,Exit1
4 Addi $17,$19,-1
5 Tstfor2: Slti $8,$17,0 # $8=1 si $17<0
6 Bne $8,$0,Exit2
7 Muli $15,$17,4
8 Add $16,$18,$15
9 Lw $24,0($16)
10 Lw $25,4($16)
11 Slt $8,$25,$24
12 Beq $8,$0,Exit2
13 Move $4,$18 # Copie paramètre $18 dans $4
14 Move $5,$17 # Copie paramètre $17 dans $5
15 Jal Change
16 Addi $17,$17,-1
17 J Tstfor2
18 Exit2 Addi $19,$19,1
Les instructions 4
19 J Tstfor1
20 Exit1
Le code de la procédure consiste en combien de boucles ?
A quoi correspondent les lignes de code 13 et 14 ?
Que fait l’instruction Jal ?
Donner le code C correspondant.
1 Addiu $29,$29,-32
2 Sw $31,20($29)
3 Sw $4,32($29)
4 Sw $5,36($29)
5 Sw $0,24($29)
6 Sw $0,28($29)
7 Lw $14,28($29)
8 Lw $24,24($29)
9 Multu $14,$14 Unsigned mult
10 Addiu $8,$14,1 Immediat unsigned
11 Slti $1,$8,101 Set less than
12 Sw $8,28($29)
13 Mflo $15 Move from lo
14 Addu $25,$24,$15
15 Bne $1,$0,-9
16 Sw $25,24($29)
17 Lui $4,4096 Load upper immed
18 Lw $5,24($29)
19 Jal 1048812
20 Addiu $4,$4,1072
21 Lw $31,20($29)
22 Addiu $29,$29,32
23 Jr $31
24 Move $2,$0
#include <stdio.h>
int
main (int argc, char *argv[])
{
int I,
int sum=0;
for (I=0; I<=100;I=I+1)
sum=sum+I
printf (“the sum from 0 to 100 is %d\n”, sum);
}
Les instructions 5
5.4. Exercice
Soit le code C suivant
Sort (int v[], int n){
Int I,J
For (I=0; I<n;I=I+1){
For (J=I-1;J>=0 && v[J]>v[J+1];J=J-1){
Swap(v,J);
}
}
Donner le code assembleur correspondant.
Les instructions 6
Université de Nantes
Région des Pays de La Loire
Feuille de travaux dirigés no 4
Introduction à l’assembleur
Exercice 4.1
On considère une valeur n sur 8 bits (voir dessin ci-dessous).
1. Donner les opérations logiques et les masques permettant de :
(a) récupérer la valeur des bits 3 et 4 ; 7 6 5 4 3 2 1 0
(b) forcer à 1 le bit 6 ; 0 1 1 0 1 0 1 0 n
(c) effectuer le complément à 1 de n ;
? ? ? ? ? ? ? ? ? m
(d) effectuer le complément à 2 de n ;
(e) forcer à 0 les 4 bits de poids faible ;
(f) tester si n est pair ;
(g) forcer à 0 les bits 1, 2, 4, 6, forcer à 1 les bits 0, 5, 7 et laisser inchangé le bit 3.
5 Correction
(a) n & 0x18 ou (n & 0x18) >> 3 pour avoir les deux bits à droite
(b) n | 0x40
(c) ˜ n
(d) (˜ n) + 1
(e) n & 0xf0
(f) (n & 0x1) ˆ 0x1
(g) (n & 0xa9) | 0xa1
2. Comment multiplier n par 13 en n’utilisant que des additions et des décalages ?
5 Correction
13n = 8n + 4n + n = 2*4n + 4n + n.
Exercice 4.2
Traduire en assembleur les structures de contrôle ci-dessous :
si condition alors choix variable selon tantque condition faire
action1 val1 : action1 action
sinon ... ftq
action2 valn : actionn
finsi défaut : actiondéfaut
finchoix
répéter pour variable = 1 jusqu’à 100 faire
action action
jusqu’à condition finpour
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 1/7
avec :
– condition : $t0 == $t1
– variable : $t0
5 Correction
choix: bne $t0, val1 , val2
action1
b finchoix
si: bne $t0, $t1, sinon
val2: ... tantque: bne $t0, $t1, fintantque
alors: action1
[...] action
b finsi
valn: bne $t0, valn , default b tantque
sinon: action2
actionn fintantque:
finsi:
b finchoix
defaut: actiondéfaut
finchoix:
li $t2, 1
li $t3, 100
repeter: action pour: bgt $t2, $t3, finpour
bne eax, edx, repeter action
add $t2,$t2,1
b pour
finpour:
Dans la suite, on considérera que l’on dispose des fonctions suivantes :
– print_char : affiche le caractère contenu dans $a0
– print_string : affiche la chaîne terminée par un 0x0 dont l’adresse se trouve dans $a0 ;
– print_int affiche l’entier se trouvant dans $a0 ;
– read_char : lit un caractère au clavier et le stocke dans $v0 ;
– read_int : lit un entier sur 32 bits au clavier et le stocke dans $v0.
Exercice 4.3
Écrire un programme en assembleur demandant deux nombres entiers positifs sur 32 bits à l’utilisateur et affichant
leur somme.
5 Correction
.text
.globl _start
_start:
la $a0, demande1
jal print_string
jal read_int
move $s0, $v0
la $a0, demande2
jal print_string
jal read_int
add $s0, $s0, $v0
la $a0, somme
jal print_string
move $a0, $s0
jal print_int
# exit()
li $v0, 10
syscall
.data
demande1: .asciiz "Premier nombre ? "
demande2: .asciiz "Deuxième nombre ? "
somme: .asciiz "La somme vaut : "
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 2/7
Exercice 4.4
Écrire un programme en assembleur demandant un entier positif sur 32 bits à l’utilisateur et lui indiquant s’il est
plus grand ou plus petit qu’un nombre à découvrir stocké dans le segment de données. Le programme devra afficher
le nombre de coups ayant été nécessaires pour trouver la bonne valeur.
5 Correction
# Trop grand / trop petit
#
# int main(void) {
# const int mystere = 17;
# int nbcoups = 0;
# int nb;
# do {
# printf("Nombre ? ");
# scanf("%d",&nb);
# if (nb < mystere) {
# printf("Trop petit\n");
# } else {
# if (nb > mystere) {
# printf("Trop grand\n");
# }
# }
# ++nbcoups;
# } while (nb != mystere);
# printf("Gagné ! Nombre de coups : ",nbcoups);
# }
.text
.globl _start
_start:
lw $t0, mystere
move $t1, $zero # nbcoups
do:
la $a0, nbstr
jal print_string
jal read_int
move $t2, $v0 # nb
if1:
bge $t2, $t0, else1
then1:
la $a0, tpstr
jal print_string
b endif1
else1:
if2:
ble $t2, $t0, endif2
then2:
la $a0, tgstr
jal print_string
endif2:
endif1:
add $t1, $t1, 1
while:
bne $t2, $t0, do
la $a0, gagnestr
jal print_string
move $a0, $t1
jal print_int
# exit()
li $v0, 10
syscall
.data
tgstr: .asciiz "Trop grand\n"
tpstr: .asciiz "Trop petit\n"
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 3/7
nbstr: .asciiz "Nombre ? "
gagnestr: .asciiz "Gagné ! Nombre de coups : "
mystere: .word 17
Exercice 4.5
1. Écrire un programme en assembleur demandant un caractère en minuscule à l’utilisateur et affichant sa
conversion en majuscule ou un message d’erreur si le caractère est hors du domaine a–z ;
5 Correction
# Mise en majuscule d’une lettre
# int main(void) {
# printf("Caractère ? ");
# scanf("%c",&car);
# if (car >= ’a’ && car <= ’z’) {
# printf("%c",’A’+(car-’a’));
# } else {
# printf("Erreur!\n");
# }
# }
.text
.globl _start
_start:
la $a0, msg
jal print_string
jal read_char
if:
blt $v0, ’a’, else
bgt $v0, ’z’, else
then:
li $t0, ’a’
sub $t0, $v0, $t0
add $a0, $t0, ’A’
jal print_char
b endif
else:
la $a0, erreur
jal print_string
endif:
# exit()
li $v0, 10
syscall
.data
caractere: .space 1
msg: .asciiz "Caractère ? "
erreur: .asciiz "Erreur!"
2. Modifier le programme précédent pour mettre en majuscules une chaîne de caractères stockée dans le seg-
ment de données. Le programme devra s’arrêter en affichant un message d’erreur si l’un des caractères de la
chaîne n’est pas une lettre minuscule.
5 Correction
# Mise en majuscule d’une chaîne de caractères
# int main(void) {
# char chaine[] = "essai";
# char *c = chaine;
# int erreur = 0;
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 4/7
# while ((*c != ’\0’) && !erreur) {
# if (*c >= ’a’ && *c <= ’z’) {
# *c = ’A’+(*c - ’a’);
# } else {
# erreur = 1;
# }
# c += 1;
# }
# if (!erreur) {
# printf("%s\n",chaine);
# } else {
# printf("Erreur!\n");
# }
# }
.text
.globl _start
_start:
la $t0, chaine # c
li $t1, 0 # erreur
while:
lb $t2, 0($t0)
beqz $t2, endwhile
bnez $t1, endwhile
if1:
blt $t2, ’a’, else1
bgt $t2, ’z’, else1
then1:
sub $t2, $t2, ’a’
add $t2, $t2, ’A’
sb $t2, 0($t0)
b endif1
else1:
li $t1, 1
endif1:
add $t0, $t0, 1
b while
endwhile:
if2:
bnez $t1, else2
then2:
la $a0, chaine
jal print_string
b endif2
else2:
la $a0, errstr
jal print_string
endif2:
# exit()
li $v0, 10
syscall
.data
caractere: .space 1
msg: .asciiz "Caractère ? "
errstr: .asciiz "Erreur!"
chaine: .asciiz "essai"
Exercice 4.6
Écrire un programme en assembleur déclarant un tableau initialisé de 10 entiers sur 32 bits et en recherchant le
plus petit et le plus grand élément.
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 5/7
5 Correction
# Recherche de plus grand et plus petit élément dans un tableau
# int main(void) {
# int tab[] = { 34, 8, -5, 9, 134, 789, 1, 3, 90, 23 };
# int petit = tab[0], grand = tab[0];
#
# for (int i=1, i < 10; ++i) {
# if (petit > tab[i]) {
# petit = tab[i];
# }
# if (grand < tab[i]) {
# grand = tab[i];
# }
# }
# printf("Plus petit élément: %i",petit);
# printf("Plus grand élément: %i",grand);
# }
.text
.globl _start
_start:
# on utilise les registres s* sans les sauvegarder car on est dans le programme principal
lw $s1, tab+0($zero) # petit
move $s2, $s1 # grand
li $s0, 4 # indice i
for:
bge $s0, 40, endfor # 40 = 10*4
lw $s3, tab+0($s0) # tab[i]
if1:
ble $s1, $s3, endif1
then1:
move $s1, $s3
endif1:
if2:
bge $s2, $s3, endif2
then2:
move $s2, $s3
endif2:
add $s0, $s0, 4
b for
endfor:
la $a0, ppelem
jal print_string
move $a0, $s1
jal print_int
la $a0, cr
jal print_string
la $a0, pgelem
jal print_string
move $a0, $s2
jal print_int
# exit()
li $v0, 10
syscall
.data
tab: .word 34, 8, -5, 9, 134, 789, 1, 3, 90, 23
pgelem: .asciiz "Plus grand élément : "
ppelem: .asciiz "Plus petit élément : "
cr: .asciiz "\n"
Exercice 4.7
Écrire un programme en assembleur testant si une chaîne de caractères est un palindrome (i.e. telle que la chaîne
inversée est identique à la chaîne elle-même). On considèrera des chaînes sans espace ni lettre accentuée.
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 6/7
5 Correction
# Test de palindrome
# int main(void) {
# char chaine[] = "laval";
# char *l = chaine;
# char *r = chaine+(strlen(chaine)-1);
# while ((l < r) && (*l == *r)) {
# l += 1;
# r -= 1;
# }
# if (*l == *r) {
# printf("Palindrome\n");
# } else {
# printf("Pas palindrome\n");
# }
# }
.text
.globl _start
_start:
# on utilise les registres s* sans les sauvegarder car on est dans le programme principal
la $s0, chaine
la $s1, finchaine
sub $s1, $s1, 1 # On se positionne sur le dernier caractère de "chaine"
while:
lb $t0, 0($s0)
lb $t1, 0($s1)
bge $s0, $s1, endwhile
bne $t0, $t1, endwhile
add $s0, $s0, 1
sub $s1, $s1, 1
b while
endwhile:
if:
bne $t0, $t1, else
then:
la $a0, palin
jal print_string
b endif
else:
la $a0, paspalin
jal print_string
endif:
# exit()
li $v0, 10
syscall
.data
chaine: .ascii "esoperesteicietserepose"
finchaine: # Astuce pour connaître l’adresse de la fin de "chaine"
palin: .asciiz "Palindrome\n"
paspalin: .asciiz "Pas palindrome\n"
Projet soutenu par le Conseil Régional Des Pays de La Loire dans le cadre des projets ENRC 2008-2009 7/7
ISITCom – Hammam Sousse A.U. 2009-2010 - Semestre 2 –Date : 24/05/2010
Architecture des ordinateurs Enseignant : R. Braham, F. Sandid
Examen Session principale
Classe : 1ère année Licence Réseaux Durée : 1h30 – Documents non autorisés
Exercice 1 : (3 pts)
a. L’architecture des ordinateurs est une branche de l’informatique. A quoi s’intéresse-t-elle ?
b. Parmi les sujets suivants, indiquer tous ceux qui sont importants pour l’architecture :
01. les bases de données
02. les réseaux
03. les systèmes d’exploitation
04. les circuits logiques
05. la programmation
06. l’algèbre de Boole
07. la fabrication des circuits intégrés
Exercice 2 : (4 pts)
Un programme de 1000 instructions s’exécute sur un processeur qui a une fréquence d’horloge de
1 GHz. On suppose qu’une instruction dure 2 cycles s’il n’y a pas de cache miss, et dure 5 cycles
d’horloge quand il y a un cache miss.
a. Calculer le temps d’exécution de ce programme si on suppose un taux de cache miss égal à
20%.
b. Calculer le CPI.
Exercice 3 : (4 pts)
La mémoire principale (RAM) d’un ordinateur est de 1024 octets. Elle est découpée en 4 pages de
même taille numérotées 0, 1, 2, 3.
1. Combien de bits sont nécessaires pour représenter une adresse ?
2. Pour chaque page, donnez l’adresse du premier et du dernier octet. Expliquer.
3. Un certain programme a besoin d’un espace mémoire de 2 Ko. Peut-on exécuter ce programme sur cet
ordinateur ? Expliquer ?
Exercice 4 : (4 pts)
Donner le chemin de donnée du MIPS pour le traitement des instructions
addi $4, $30, 30
sw $4, 20($20)
Donner un seul schéma. Expliquer votre réponse.
Exercice 5 : (5 pts)
Considérer la partie suivante d’un programme pour le processeur MIPS (étudié en classe) :
lw $2, ($1)
lw $4, 4($1)
add $5, $2, $4
add $6, $4, $5
sw $6, 24($1)
add $6, $5, $6
addi $8, $0, 50
add $3, $6, $8
sw $3, 20($1)
avec les valeurs suivantes avant l’exécution de cette partie de programme: $1=500 ; Mémoire
[500]=50 ; Mémoire [504]= -10.
Expliquer les changements qui se font après l’exécution de chaque instruction.