Université de Bordeaux

U.F. Informatique

Licence Informatique 2ème année

Année 2025 -- 2026

ARCHITECTURE DES ORDINATEURS

Devoir Surveillé 1 - Sujet 1

1 heure 20 minutes

sans documents

# EXERCICE 1 [50 points]

## Question 1.1 [10 points]

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 : P = 8023 et
R = CDBA, qui répondent à ces critères.

## Question 1.2 [10 points]

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. Il en découle que :
8000 < FFFF < 0000 < 7FFF. On a donc :

P = 8023 < R = CDBA < Q = 3FD6 < M = 4829 < N = 71F2, soit :
P < R < Q < M < N.

## Question 1.3 [10 points]

      M = 0100 1011 0010 1001
    + P = 1000 0000 0010 0011
    =     1100 1011 0100 1100
    =        C    B    4    C

Il n'y a pas eu perte de retenue, ni débordement ("overflow") car le
résultat n'est pas sorti du domaine représentable en machine : on ne
peut avoir de débordement lorsqu'on ajoute deux nombres de signe
opposé.

## Question 1.4 [20 points]

     Q = 0011 1111 1101 0110

Le complément à deux de Q est :

    /Q = 1100 0000 0010 1001
    +1 = 1100 0000 0010 1010

donc :

    -Q =    C    0    2    A

qui est bien un nombre négatif.

P-Q = P+(-Q)

      P = 1000 0000 0010 0011
    +-Q = 1100 0000 0010 1010
    =   1 0100 0000 0100 1101
    =        4    0    4    D

Il y a eu perte de retenue, et aussi 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.


# Exercice 2 [150 points]

## Question 2.1 [20 points]

La fonction `mystere` semble avoir un unique paramètre, qui est empilé
avant l'appel de la fonction, à l'adresse 0x00c. Le fait qu'il
s'agisse d'un paramètre et pas de sauvegarde "_caller save_" peut être
vérifié en constatant que la valeur empilée est supprimée au retour de
la fonction, par l'instruction `iaddl 4,%esp` à l'adresse 0x013. Elle
semble également avoir une valeur de retour, qui est placée en mémoire
dans la variable `x` au retour de l'appel, à l'adresse 0x019. Cette
valeur de retour a l'air d'être un entier et non une adresse.

Le paramètre qui est empilé semble être une adresse mémoire, égale à
l'étiquette `t`. La fonction retourne une valeur entière. Le prototype
de la fonction pourrait donc être :

    long mystere (long * t);

## Question 2.2 [20 points]

L'instruction d'adresse 0x026 sert à placer dans le registre `ebx` le
paramètre de la fonction (une adresse de zone mémoire), à partir de la
pile. La valeur immédiate de cette instruction est `16` car, au début
de la fonction, on a effectué l'empilage de la valeur de trois
registres "_callee save_" (`ebx`, `esi` et `edi`), pour pouvoir
utiliser ceux-ci dans la fonction. L'adresse de retour de la fonction
est donc maintenant accessible à `esp+12`, et le premier paramètre est
à l'adresse `esp+16`.

## Question 2.3 [10 points]

L'instruction d'adresse 0x067 sert à restaurer le registre "_callee
save_" `edi` à la fin de la fonction `mystere`, ce qui a permis de
l'utiliser sans détruire son contenu avant appel. Le contenu du
registre a été sauvegardé par l'instruction à l'adresse 0x024.

## Question 2.4 [10 points]

La valeur qui sera placée dans `x` à la fin du programme est la valeur
entière `3`. En effet, lors de l'appel à `mystere (t)`, cette fonction
parcourt le tableau dont l'adresse a été passée en paramètre, et
incrémente `eax`, qui a été initialisé à `0` au début de la fonction,
chaque fois que l'on avance d'une case. Le parcours s'arrête dès lors
que la valeur de la case suivante est égale à celle de la case
courante. Ici, dans le tableau, la première des deux valeurs `7` qui
se suivent est à l'indice `3`, qui est retourné.

## Question 2.5 [10 points]

Dans ce cas, aucun doublon n'ayant été trouvé avant la valeur
sentinelle `0`, c'est la valeur `-1` qui sera retournée.

## Question 2.6 [30 points]

`ebx` semble être un pointeur, qui parcourt le tableau de façon
croissante (adresse 0x049). La valeur qu'il pointe est lue à chaque
tour de boucle (adresse 0x04f), pour être mise dans `ecx`, pour test
d'égalité avec la valeur précédente contenue dans `edi` (adresse
0x05e), après avoir vérifié qu'elle n'était pas égale à `0` (adresse
0x055).

`ecx` semble être un registre de travail stockant la valeur lue depuis
la case du tableau pointée par `ebx` (adresse 0x04f).

`edi` semble être un registre de travail stockant la valeur précédente
de celle actuellement pointée par `ebx`, qui est dans `ecx`. À chaque
tour de boucle, la valeur courante de `ecx` est transférée dans `edi`
(adresse 0x041), avant de lire la valeur de la nouvelle case courante.

`edx` semble être un registre de travail stockant l'indice de la case
précédant la case courante du tableau. Il est initialisé à `-1` par
copie depuis `eax` (adresse 0x03f), et incrémenté à chaque tour de
boucle (adresse 0x043).

`esi` semble être un registre temporaire, servant à la comparaison des
valeurs de la case courante et de la case qui la précède, par
soustraction entre `ecx` et `edi` (adresse 0x05e).

`eax` est la valeur de retour de la fonction. Elle est préinitialisée
à `-1` en début de fonction (adresse 0x02c), puis éventuellement mise
à jour avec l'indice de la case précédente si un doublon est trouvé
(adresse 0x065).

## Question 2.7 [10 points]

`myst1` est l'étiquette de début de boucle, qui sert à reboucler
(adresse 0x060) tant que la valeur de la case courante n'est pas égale
à la valeur de la case précédente.

`myst2` est l'adresse de sortie de la boucle lorsque la valeur
sentinelle zéro a été rencontrée (adresse 0x057).

## Question 2.8 [10 points]

La fonction `mystere` renvoie l'indice de la première des deux valeurs
identiques consécutives rencontrées en premier dans le tableau, ou
`-1` lorsqu'aucun doublon n'a été rencontré jusqu'à la valeur
sentinelle `0`.

## Question 2.9 [10 points]

La valeur correspondant au registre `eax` est `0`. On le voit par
comparaison entre les deux instructions `irmovl` d'adresses 0x000 et
0x006.

La valeur correspondant au registre `ecx` est `1`. On le voit par la
répétition contenue à l'instruction d'adresse 0x036.

La valeur correspondant au registre `esi` est `6`. On le voit par la
comparaison entre les deux instructions `pushl` d'adresses 0x020 et
0x022.

## Question 2.10 [20 points]

Le code de l'instruction d'adresse 0x049, qui correspond à
l'instruction `iaddl 4,%ebx`, est :

    c0 83 04 00 00 00

Le premier octet est l'opcode. La valeur `c0` correspond à
l'instruction `iaddl` ; cette valeur est analogue à celle de
l'instruction d'adresse 0x043.

En ce qui concerne le deuxième octet, qui contient les numéros de
registres impliqués, on constate, par comparaison avec cette même
instruction d'adresse 0x043, que `3` correspond à `ebx` et `2` à
`edx`. La valeur `f` correspond à l'absence d'un second registre.

Les quatre derniers octets contiennent, au format _little endian_, la
valeur immédiate à ajouter, ici égale à `0x00000004`.
