Université de Bordeaux U.F. Informatique Licence Informatique 2ème année Année 2018 -- 2019 ARCHITECTURE DES ORDINATEURS Devoir Surveillé 1 1 heure 20 minutes sans documents * QUESTION 1 [5 points] ============ * Question 1.1 [1 point] Ceux 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 = 9876, N = F00D et Q = C0DE, 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 = 9876 < Q = C0DE < N = F00D < R = 1418 < P = 3945, soit : M < Q < N < R < P. * Question 1.3 [1 point] N = 1111 0000 0000 1101 + Q = 1100 0000 1101 1110 = 1 1011 0000 1110 1011 = B 0 E B Il n'y a pas eu débordement ("overflow"), car le résultat n'est pas sorti du domaine représentable en machine. On a ajouté deux nombres négatifs ensemble. Q = C0DE est assez proche de 0, et F00D est aussi très proche de 0. Le résultat, B0EB, s'éloigne un peu plus de 0, mais reste représentable. On pourrait avoir débordement en ajoutant deux nombres négatifs plus grands en valeur absolue (qui pourraient alors donner un nombre négatif trop petit en valeur signée, qui apparaîtrait comme un nombre positif), ou en ajoutant deux nombres positifs trop grands en valeur absolue (cela pourrait donner un nombre positif trop grand en valeur signée, qui apparaîtrait comme un nombre négatif). Ce n'est pas le cas ici : l'ajout des deux nombres négatifs reste un nombre négatif. * Question 1.4 [2 points] N = 1111 0000 0000 1101 Le complément à deux de N est : /N = 0000 1111 1111 0010 +1 = 0000 1111 1111 0011 donc : -N = 0 F F 3 qui est un nombre positif. M-N = M+(-N) M = 1001 1000 0111 0110 +-N = 0000 1111 1111 0011 = 0 1010 1000 0110 1001 = A 8 6 9 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 2 [2 points] ============ 2.1 - A.B.C.D [0,5 points] 2.2 - NOT (A+B+C+D) [0,5 points] 2.3 - A+B+C+D [0,5 points] 2.4 - NOT(A.B.C.D) [0,5 points] * QUESTION 3 [9 points] ============ * Question 3.1 [1 point] En prenant les paramètres dans l'ordre inverse de leur empilage, à partir du "call mystere" (adresses 0x006 à 0x015), on a : - l'adresse de t, qui semble être le début d'un tableau ; - la valeur constante 4, un nombre entier, possiblement la taille du tableau t ? Le code correspondant se trouve entre les adresses 0x006 et 0x015. * Question 3.2 [6 points] Explication synthétique : [1,5 points] La fonction "mystere" effectue une "rotation vers les adresses basses", d'une case, des éléments du tableau dont l'adresse "t" est passée en premier paramètre, et la taille "n" en second paramètre. Ainsi, pour tout i tel que 0 <= i < (n-1), t[i] reçoit t[i+1], et t[n-1] reçoit t[0]. Utilisation des registres : [1,5 points] - %edx : adresse de la case courante du tableau à écrire, initialisée à partir de l'adresse passée en premier paramètre. Cette adresse est incrémentée (de 4 octets) à chaque tour de boucle ; - %ecx : nombre d'éléments du tableau restant à traiter, initialisé à partir de la valeur passée en deuxième paramètre. Cette valeur est décrémentée à chaque tour de boucle ; - %eax : valeur de la cellule suivante du tableau, transferée en mémoire à l'adresse de la cellule courante pointée par %edx. Cette valeur est lue et écrite à chaque tour de boucle. Test d'adresse 0x059 : [1 point] Il sert à effectuer un nouveau tour de boucle tant que toutes les cases du tableau n'ont pas été décalées. Instruction d'adresse 0x05e : [1 point] Elle sert à récupérer l'ancienne zéroième valeur du tableau, qui avait été sauvegardée par empilement avant la boucle de décalage, pour l'écrire en dernière position du tableau. Modification en mémoire : [1 point] Suite à l'exécution de la fonction, la mémoire est modifiée de la fonction suivante : 0x100: 07000000 0x104: 01000000 0x108: 03000000 0x10c: 02000000 * Question 3.3 [1 point] Le test de l'adresse 0x034 sert à ne pas effectuer le décalage des éléments du tableau lorsque la taille de celui-ci est inférieure ou égale à 1. * Question 3.4 [1 point] void mystere (int * t, int n); * QUESTION 4 [4 points] ============ swap: mrmovl 4(%esp),%edx # Lit p dans %edx mrmovl 8(%esp),%ecx # Lit q dans %ecx mrmovl (%edx),%eax # Lit *p dans %eax pushl %eax # Sauvegarde *p mrmovl (%ecx),%eax # Lit *q dans %eax rmmovl %eax,(%edx) # Écrit l'ancien *q dans *p popl %eax # Récupère l'ancien *p rmmovl %eax,(%ecx) # Écrit l'ancien *p dans *q ret On a bien pris garde, dans le code de la fonction en question, de n'utiliser que des registres "caller save", que l'on peut modifier sans avoir besoin de les sauvegarder au préalable. Le fait d'empiler %eax revient à utiliser un registre supplémentaire, dont on a besoin car il faut lire les deux valeurs dans des registres avant de les réécrire en mémoire de façon permutée.