Université de Bordeaux U.F. Informatique Licence Informatique 2ème année Année 2019 -- 2020 ARCHITECTURE DES ORDINATEURS Devoir Surveillé 1 1 heure 20 minutes sans documents * QUESTION 1 [5 points] ============ * Question 1.1 [1 point] Les nombres qui sont négatifs sont ceux dont le bit de poids le plus fort (bit de signe) est à 1, c'est-à-dire dont le premier demi-octet est compris entre 8 et F. Les nombres négatifs sont donc : M = ABAD et Q = DADA, qui répondent à ces critères. * Question 1.2 [1 point] Le plus petit nombre négatif est 8000 (en tant que nombre signé), le plus grand nombre négatif est FFFF, le plus petit nombre positif est 0000, et le plus grand nombre positif est 7FFF. On a donc : 8000 < FFFF < 0000 < 7FFF. On a donc : M = ABAD < Q = DADA < N = 1DEA < P = 3456 < R = 789A, soit : M < Q < N < P < R. * Question 1.3 [1 point] P = 0011 0100 0101 0110 + Q = 1101 1010 1101 1010 = 1 0000 1111 0011 0000 = 0 F 3 0 Même s'il y a eu retenue, il n'y a pas eu débordement ("overflow"), parce que l'ajout de deux nombres de signes opposés ne permet pas de sortir du domaine de représentation. * Question 1.4 [2 points] R = 0111 1000 1001 1010 Le complément à deux de R est : /R = 1000 0111 0110 0101 +1 = 1000 0111 0110 0110 donc : -R = 8 7 6 6 qui est bien un nombre négatif. M-R = M+(-R) M = 1010 1011 1010 1101 +-R = 1000 0111 0110 0110 = 1 0011 0011 0001 0011 = 3 3 1 3 Il y a eu débordement ("overflow"), car le résultat est sorti du domaine représentable en machine : en ajoutant deux nombres négatifs, on a obtenu un nombre positif. * QUESTION 2 [7 points] ============ * Question 2.1 [1 point] Le produit P sera codé sur 4 bits au plus. En effet, la valeur maximale pour chacun des facteurs est 11 = 3, et leur produit est 9 = 1001, qui est codé sur 4 bits. * Question 2.2 [2 points] Les vecteurs de vérité (tables logiques) des fonctions S et C sont : s (x, y) = 0 1 1 0 = XOR (x, y) c (x, y) = 1 0 0 0 = AND (x, y) * Question 2.3 [4 points] Chaque produit partiel s'exprime comme un nombre dont chaque bit est le résultat du produit du bit correspondant de A par le même bit b_i : A . b_0 = (a_1.b_0) (a_0.b_0) A . b_1 = (a_1.b_1) (a_0.b_1) Le résultat final est obtenu en sommant par colonnes : 0 0 (a_1.b_0) (a_0.b_0) + 0 (a_1.b_1) (a_0.b_1) 0 ------------------------------------- p_3 p_2 p_1 p_0 On a donc : p_0 = a_0.b_0 p_1 = HA:s (a_1.b_0, a_0.b_1) = XOR (a_1.b_0, a_0.b_1) p_2 = HA:s (a_1.b_1, HA:c (a_1.b_0, a_0.b_1)) = XOR (a_1.b_1, AND (a_1.b_0, a_0.b_1)) p_3 = HA:c (a_1.b_1, HA:c (a_1.b_0, a_0.b_1)) = AND (a_1.b_1, AND (a_1.b_0, a_0.b_1)) = AND (a_1.b_1, a_1.b_0, a_0.b_1) * QUESTION 3 [8 points] ============ * Question 3.1 [1 point] En étudiant les instructions d'empilement dans l'ordre inverse à partir de l'instruction "call mystere" (adresses 0x006 à 0x00e), on observe que l'on empile l'adresse de t, qui semble être le début d'un tableau et, en tout état de cause, le seul paramètre de la fonction (une seule instruction "pushl" avant le "call"). * Question 3.2 [6 points] Explication synthétique : [1,5 points] La fonction "mystere" replace par sa valeur double chacun des éléments du tableau commençant à l'adresse t, jusqu'à trouver un élément de valeur nulle, et renvoie le nombre de cases qui ont été ainsi modifiées. a) Utilisation des registres : [1,5 points] - %edx : c'est le pointeur qui contient l'adresse de la case courante du tableau, qu'il parcourt case après case. - %eax : c'est le nombre courant de cases du tableau qui ont été modifiées. - %ecx : c'est un registre de travail, qui reçoit la valeur de la case courante du tableau, où elle est doublée. b) Test d'adresse 0x034 : [1 point] Il sert à sortir de la boucle dès qu'une case de valeur nulle a été trouvée. c) Instruction d'adresse 0x45e : [1 point] Elle sert à passer à la case suivante du tableau, dont l'adresse est située 4 octets après l'adresse de la case précédente. d) Modification en mémoire : [1 point] Suite à l'exécution de la fonction, la mémoire est modifiée de la fonction suivante : 0x100: 03000000 : nombre de cases modifiées 0x104: 04000000 : valeur doublée 0x108: 08000000 : valeur doublée 0x10c: 0E000000 : valeur doublée (la valeur suivante est inchangée) * Question 3.3 [1 point] int mystere (int * t);