28 | | - En bas à gauche, c'est le code de boot qui, ici, se contente d'initialiser la pile d'exécution du noyau et d'entrer dans le noyau par la fonction `kinit()` (kernel init). Ce code s'exécute en mode `kernel`, mais il ne fait pas partie du noyau car dans un vrai système, il devrait charger le noyau depuis le disque, mais, ici, le noyau est déjà en mémoire. |
29 | | - En bas, c'est le noyau avec la fonction `kinit()` qui initialise les structures de données internes du noyau, ici, il s'agit juste de mettre les variables globales non initialisées à 0, puis d'appeler la routine `app_load` qui va entrer dans la première fonction de l'application nommée `_start()`. Dans le noyau, on voit aussi, la routine `kentry` qui est le point d'entrée du noyau pour la gestion des services, ici, il n'y a que le gestionnaire d'appel système (`syscall`). Son comportement est succinctement résumé. |
30 | | - En haut, c'est l'application, décomposée en trois parties. La première à gauche est la fonction `_start()` appelée par le noyau au début de l'application. Cette fonction initialise les variables globales, puis appelle la fonction `main()`. Si on sort de la fonction `main()`, elle fait l'appel système `exit()`. La seconde partie au centre contient le code de l'utilisateur ''(notez que la fonction `main()` ou l'une des fonctions appelées par la fonction `main()` peut demander une sortie anticipée de l'application en appelant directement `exit()`)''. Enfin, la troisième partie, à droite, c'est le code des bibliothèques système utilisées par l'application, ce sont elles qui font les appels système, ici, seule la fonction `clock()` est représentée. |
31 | | |
32 | | |
33 | | |
34 | | = 1. Les modes d'exécution du MIPS |
| 28 | - En bas à gauche, c'est le code de boot qui, ici, se contente d'initialiser la pile d'exécution du noyau et d'entrer dans le noyau par la fonction `kinit()` (kernel init). Ce code s'exécute en mode `kernel`, mais il ne fait pas partie du noyau car, dans un vrai système, il doit charger le noyau depuis le disque dur, mais, ici, le noyau est déjà en mémoire alors c'est plus simple. |
| 29 | - En bas, c'est le noyau avec la fonction `kinit()` qui initialise les structures de données internes du noyau. Ici, il s'agit juste de mettre les variables globales non initialisées à 0, puis d'appeler la routine `app_load` qui va entrer dans la première fonction de l'application utilisateur nommée `_start()`. Dans le noyau, sur la figure, on voit aussi la routine `kentry` qui est le point d'entrée du noyau pour la gestion des services. Actuellement, il n'y a que le gestionnaire d'appel système (`syscall`). Son comportement est succinctement résumé. |
| 30 | - En haut, c'est l'application utilisateur, décomposée en trois parties. La première à gauche est la fonction `_start()` appelée par le noyau au tout début de l'application. Cette fonction initialise à 0 les variables globales non initialisées dans le programme, puis elle appelle la fonction `main()`. Si on sort de la fonction `main()` avec un `return`, la fonction `_start` fait l'appel système `exit()`. La seconde partie au centre contient le code de l'utilisateur ''(notez que la fonction `main()` ou l'une des fonctions appelées par la fonction `main()` peut demander une sortie anticipée de l'application en appelant directement `exit()`)''. Enfin, la troisième partie, à droite, c'est le code des bibliothèques système utilisées par l'application, ce sont elles qui font les appels système, ici, seule la fonction `clock()` est représentée. |
| 31 | |
| 32 | |
| 33 | |
| 34 | = 1. Les modes d'exécution du MIPS et les instructions ''système'' |
59 | | 1. Le MIPS propose des registres à usage général (GPR ''General Purpose Register'') pour les calculs ($0 à $31). Le MIPS propose un deuxième banc de registres à l'usage du système d'exploitation, ce sont les registres système (dans le coprocesseur 0).\\Comment sont-ils numérotés? Chaque registre porte un nom correspondant à son usage, quels sont ceux que vous connaissez: donner leur nom, leur numéro et leur rôle? Peut-on faire des calculs avec des registres? Quelles sont les instructions qui permettent de les manipuler? (C10 S5+S11) |
| 59 | 1. Le MIPS propose des registres à usage général (GPR ''General Purpose Register'') pour les calculs ($0 à $31).\\ |
| 60 | Le MIPS propose un deuxième banc de registres **à l'usage du système d'exploitation** dans le coprocesseur 0.\\ |
| 61 | Chaque registre **''système''** porte un nom correspondant à son usage, nous en avons vu 3 en cours (C10 S7+S10 à S14) : `c0_sr`, `c0_cause` et `c0_epc`.\\ |
| 62 | Donner leur numéro et leur rôle en une phrase ? |
71 | | - non, il n'est pas possible de faire des calculs sur ces registres. |
72 | | - On peut juste les lire et les écrire en utilisant les instructions `mtc0` et `mfc0` |
73 | | '' |
74 | | }}} |
75 | | 1. Le registre status est composé de plusieurs champs de bits qui ont chacun une fonction spécifique.\\Décrivez le contenu du registre status et le rôle des bits de l'octet 0 (seulement les bits vus en cours). (C10 S12+S13+S15) |
| 74 | '' |
| 75 | }}} |
| 76 | 1. Les deux instructions qui permettent de les manipuler sont `mtc0` et `mfc0` (C10 S11).\\ |
| 77 | Quelle est leur syntaxe ?\\ |
| 78 | Est-ce qu'on peut manipuler ces registres **''système''** avec d'autres instructions ?\\ |
| 79 | Écrivez les instructions permettant de faire `c0_epc = c0_epc + 4` (vous utiliserez le registre GPR `$8`) |
| 80 | {{{#!protected ------------------------------------------------------------------------------------ |
| 81 | '' |
| 82 | || `mtc0 $GPR, $C0` || `M`ove `T`o `C`oprocessor `0` || `$GPR` → COPRO_0(`$C0`) |
| 83 | || `mfc0 $GPR, $C0` || `M`ove `F`rom `C`oprocessor `0` || `$GPR` ← COPRO_0(`$C0`) |
| 84 | - Attention à l'ordre des registres dans les instructions.\\ |
| 85 | L'ordre est toujours le même, c'est d'abord le registre $GPR puis le registre $C0, le sens de l'échange est défini par l'opcode de l'instruction (move `TO` ou move `FROM` coprocessor 0).\\ |
| 86 | `$C0` peut être `c0_sr` (i.e. $12) ou `c0_cause` (i.e. $13) ou `c0_epc` (i.e. $14) |
| 87 | - non, il n'est pas possible d'utiliser d'autres instructions pour les manipuler, on peut juste les lire et les écrire en utilisant les instructions `mtc0` et `mfc0`\\ \\ |
| 88 | - `c0_epc = c0_epc + 4` |
| 89 | {{{#!c |
| 90 | mfc0 $8, $14 |
| 91 | addiu $8, $8, 4 |
| 92 | mtc0 $8, $14 |
| 93 | }}} |
| 94 | '' |
| 95 | }}} |
| 96 | 1. Le registre status est composé de plusieurs champs de bits qui ont chacun une fonction spécifique.\\Décrivez le contenu du registre status et le rôle des bits 0, 1 et 4 de l'octet 0. (C10 S12+S13+S15) |