Quiz partie 2 : Les grands principes de l’exécution
Question 1
À quoi sert l'unité arithmétique et logique (ALU) d'un processeur ?
À stocker les résultats des opérations numériques
À contrôler les accès à la mémoire
À réaliser des opérations élémentaires de calcul
À réaliser des mesures sur des valeurs logiques
Réponse
Choix 3. L'ALU est la partie du processeur qui réalise toutes les opérations de calcul du processeur. Pour cela, elle a besoin de données écrites en mémoire et de registre pour les manipuler rapidement, mais ce ne sont pas des éléments de l'ALU.
Question 2
Cochez toutes les propositions vraies. (Plusieurs réponses sont possibles).
Les registres d'un processeur permettent un accès rapide aux données manipulées par l'ALU.
Un des registres du processeur contient l'adresse courante du programme en cours.
Un des registres du processeur indique l'adresse courante de la pile système.
Un des registres du processeur est dédié pour sauver l'état du processeur quand le système n'est plus alimenté.
Réponse
Choix 1,2 et 3. Comme vous l'avez vu dans le premier chapitre de cette partie, les registres d'un processeur sont utilisés pour stocker rapidement des données, mais aussi pour mémoriser l'avancée du programme et l'adresse actuelle de la pile système. Tous les registres sont volatiles et ne permettent pas de sauver des valeurs si le système n'est pas alimenté.
Question 3
Laquelle des affirmations suivantes est-elle fausse ?
Un FPGA est un circuit qui, une fois conçu et déployé sur la carte, ne peut pas être reprogrammé.
Un DSP est principalement dédié aux calculs de traitement de signaux.
Un microprocesseur est peu adapté aux systèmes embarqués à cause de sa trop grande consommation d'énergie.
Un microcontrôleur offre une grande variété d'unités périphériques pour interagir avec son environnement.
Réponse
Choix 1. Le circuit d'un FPGA n'est pas figé. Une fois programmé, il est tout à fait possible de synthétiser un nouveau circuit et de le reprogammer. Pour certains d'entre eux, il est même possible de le faire pendant leur exécution.
Question 4
Regardez la capture d’écran ci-dessous. L'instruction ADDS Rd,Rn,#Const affecte au registre Rd la valeur Rn + Const.
Après avoir réalisé les trois instructions stockées aux adresses 0x08000376 à 0x0800037C, quelle est la proposition vraie ?
1.
R1 = 0xC
R2 = 0xC
R3 = 0x8
2.
R1 = 0x0E
R2 = 0x04
R3 = 0x12
3.
R1 = 0x2
R2 = 0xA
R3 = 0x8
4.
R1 = 0xE
R2 = 0x4
R3 = 0xF
Réponse
Choix 2. Si on suit pas-à-pas les calculs réalisés, nous avons au début les registres R1, R2 et R3 qui ont pour valeur :
R1 = 0x02
R2 = 0x00
R3 = 0x04
Après la ligne ADDS r2,r1,#2 :
R1 = 0x02
R2 = 0x04
R3 = 0x04
puis avec ADDS r1,r2,#0x0A :
R1 = 0x0E
R2 = 0x02
R3 = 0x04
et enfin après ADDS R3,R1,#4 :
R1 = 0x0E
R2 = 0x04
R3 = 0x12
Question 5
Correcte
Sachant que :
l'instruction MOV Rd,Rn copie le registre Rn dans Rd,
l'instruction ADDS Rd,Rn,#Const affecte au registre Rd la valeur Rn + Const,
l'instruction LDR Rt,[Rn,#Const] charge dans le registre Rt la valeur stockée à l'adresse de Rn décalée de #Const,
l'instruction STR Rt,[Rn,#Const] enregistre à l'adresse Rn décalée de #Const la valeur courante du registre Rt,
l'instruction CMP Rn,#Const compare la valeur de Rn avec #Const et met à jour les fanions,
l'instruction BGE #Const effectue un saut à l'adresse #Const si les fanions indiquent une valeur plus grande ou égale.
Regardez à présent la capture d'écran ci-dessous.
Quelle est la proposition vraie lorsque le programme arrive à l'adresse 0x080003A6 (on n'exécute pas cette ligne) ?
1.
R0 = 0x0000ACC0
R1 = 0x20000000
R2 = 0x02
R3 = 0x04
R4 = 0x00
2.
R0 = 0xC0AC0000
R1 = 0x20000000
R2 = 0x02
R3 = 0x04
R4 = 0x00
3.
R0 = 0xC0AC0002
R1 = 0x20000000
R2 = 0x02
R3 = 0x04
R4 = 0x20000000
4.
R0 = 0x0000ACC2
R1 = 0x20000000
R2 = 0x02
R3 = 0x04
R4 = 0x20000000
Réponse
Choix 1. La première instruction copie dans r0 la valeur de r1, soit 0x20000000. L'instruction suivante LDR r0,[r0,#0x00] va charger la valeur contenue à l'adresse de r0, soit à l'adresse 0x20000000, dans le registre R0.
Pour connaître cette valeur, il faut consulter la Memory Windows (en bas de la capture d'écran) et ne pas oublier que les valeurs sont stockées en mémoire avec la convention little endian. Il faut donc lire les valeurs “à l'envers”, soit ici la valeur 0x0000ACC0.
Cette valeur étant plus grande que 0x0A, l'instruction BGE effectue le saut à la ligne 0x080003A6, qui est la ligne d'arrivée… On a donc dans les registres les valeurs :
R0 = 0x0000ACC0
R1 = 0x20000000
R2 = 0x02
R3 = 0x04
R4 = 0x00
Question 6
Supposons que vous avez les valeurs suivantes dans les registres R0 = 0x01, R1 = 0x00000002, R2 = 0x00000005 et R3 = 0x00000007 et que la pile contient la liste suivante (le pointeur de pile est sur l'élément le plus bas) :
En réalisant la suite d'instructions suivante :
PUSH {r0}
POP {r1}
POP {r2}
PUSH {r3}
POP {r2}
POP {r3}
Quelles valeurs y a-t-il dans les registres ?
1.
r0 = 0x10000000
r1 = 0x00000001
r2 = 0x00000005
r3=0x20000000
2.
r0 = 0x00000001
r1 = 0x00000002
r2 = 0x10000000
r3=0x20000000
3.
r0 = 0x00000001
r1 = 0x00000001
r2 = 0x00000007
r3=0x20000000
4.
r0 = 0x10000000
r1 = 0x00000002
r2 = 0x20000000
r3=0x30000000
Réponse
Choix 3.
Pour rappel, l'instruction PUSH dépose une valeur sur la pile alors que l'instruction POP récupère la valeur la plus haute, soit :
Question 7
Incorrecte
Parmi les affirmations suivantes, laquelle est-elle fausse ?
Le passage des paramètres lors de l'appel d'une fonction peut se faire par les registres du processeur.
Le passage des paramètres lors de l'appel d'une fonction peut se faire par la pile système.
La pile système ne doit pas être modifiée au cours de l'exécution d'une fonction.
Le registre LR est utilisé pour stocker l'adresse de retour d'une fonction.
Réponse
Choix 3. Comme vous l'avez vu, le passage des paramètres à une fonction se fait soit par les registres soit par la pile (en fonction du nombre de paramètres). Le retour au programme appelant une fonction se fait bien à l'aide du registre LR dans lequel est stockée l'adresse de retour.
Par contre, rien n'interdit au programmeur ou au compilateur de manipuler la pile système dans une fonction. Il faut juste bien faire attention à ne pas la corrompre en modifiant le registre SP et s’assurer la pile ne dérive pas entre 2 appels à la fonction.
Question 8
Parmi les propositions suivantes, laquelle est-elle vraie ?
Quand une interruption survient, tous les registres sont sauvés sur la pile système.
Il existe un handler par défaut pour chaque interruption.
Les priorités des interruptions sont fixées par le matériel et ne peuvent pas être configurées.
Si une interruption survient en même temps qu'une autre, elle attend la fin de la première pour être traitée.
Réponse
Choix 2. Suite à une interruption, seuls les registres R0, R1, R2, R3, R12, xPSR et LR sont sauvés sur la pile, les autres seront perdus au retour d'interruption (le compilateur se charge de faire attention à cela).
Il est possible de fixer logiciellement le niveau de priorité de chaque interruption. Dans une architecture ARM, c'est le rôle du NVIC que de gérer ces configurations.
Les priorités servent à déterminer dans quel ordre il faut traiter les interruptions quand elles se cumulent ou arrivent en même temps. Ainsi une interruption peut-être interrompue par une interruption plus prioritaire (avec une valeur de priorité plus petite).
Question 9
Je vous rappelle qu'en C, l'opérateur % réalise un modulo sur la valeur. Ainsi, x%2 permet de tester si x est paire ou impaire.
La capture d'écran ci-après décrit un code avec une interruption.
En supposant que l'interruption :
peut survenir plusieurs fois,
peut arriver n'importe quand,
est plus prioritaire que le main,
quelles valeurs peut prendre la variable globale n ?
N'importe quelle valeur positive
Les valeurs 0 et 1
Les valeurs –1, 0 et 1
Les valeurs 0, 1 et 2
Réponse
Choix 1;
Par défaut, le programme principal fait passer n à chaque tour de boucle de 0 à 1 ou de 1 à 0.
Cependant, une interruption peut interrompre l'exécution principale n'importe quand. Il est donc possible que l'interruption survienne entre les lignes 12 et 13. Si n vaut 0, la variable est incrémentée de 1 dans l'interruption (ligne 25) puis de nouveau de 1 en revenant dans le main (ligne 13). Elle vaut donc 2 après la ligne 13. En restant dans la boucle, la variable n passera donc maintenant de la valeur 2 à la valeur 3.
Si une nouvelle interruption survient juste après le test ligne 12 alors que n vaut 2, l'interruption incrémentera de nouveau n de 1 (ligne 25) puis encore de 1 en revenant ligne 13. On aura donc une valeur de 4 pour n.
En appliquant le même raisonnement à chaque interruption, n peut prendre n'importe quelle valeur positive.