Changes between Version 90 and Version 91 of Archi-1-TP10
- Timestamp:
- Nov 25, 2021, 5:33:15 PM (4 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Archi-1-TP10
v90 v91 323 323 Cours 10 / slide 40 324 324 - La fonction `syscall()` a 5 a arguments 325 - Elle reçoit ses 4 premiers arguments dans les registres $4 à $7 et le 5e dans la pile.325 - Elle reçoit ses 4 premiers arguments dans les registres $4 à $7 et le 5e (le numéro de service) dans la pile. 326 326 - La ligne 3 sert à dire que syscall est une étiquette utilisée dans un autre fichier. `.globl` signifie **glob**al **l**abel. Si on la retire, il y aura un problème lors de l'édition de lien. `syscall()` ne sera pas trouvé par l'éditeur de liens. 327 327 - Le noyau attend le numéro de service dans `$2`. Or le numéro du service est le 5e arguments de la fonction `syscall()`. La ligne 5 permet d'aller le chercher dans la pile. … … 341 341 1. Comment imposer le placement d'adresse d'une fonction ou d'une variable en mémoire? 342 342 {{{#!protected ------------------------------------------------------------------------------------ 343 ''''''''''''''' 343 '' 344 Cours 9 / slide 24 et Cours 10 / slides 64 et 65 344 345 - C'est l'éditeur de lien qui est en charge du placement en mémoire du code et des données, et c'est dans le fichier ldscript `kernel.ld` ou `user.ld` que le programmeur peut imposer ses choix. 345 346 - Pour placer une fonction à une place, la méthode que vous avez vu consiste 346 347 - à créer une section grâce à la directive `.section` en assembleur ou à la directive `__attribute__((section()))` en C 347 348 - puis à positionner la section créée dans la description des `SECTIONS` du ldscript. 348 ''''''''''''''' 349 }}} 350 1. Dans la question **A2.5**, nous avons vu comment la fonction `kinit()` appelle la fonction `__start()` grâce à un bout de code en assembleur placé au début de la section `.text`. Nous allons voir maintenant quelles sont les conditions de cet appel. Dans le code de la question **A2.5**, `$26` est un registre de travail pour le kernel. Quels sont les autres registres modifiés? Expliquez pour chacun la valeur affectée. 351 {{{#!protected ------------------------------------------------------------------------------------ 352 ''''''''''''''' 349 '' 350 }}} 351 1. Regardons comment la fonction `kinit()` appelle la fonction `__start()`, il y a deux fichiers impliqués `kinit.c` et `hcpua.S`, les commentaires ont été rétirés. 352 {{{#!c 353 kinit.c: 354 void kinit (void) 355 { 356 [...] 357 extern int _start; // _start is the entry point of the app (defined in kernel.ld) 358 app_load (&_start); // function to start the user app (defined in hcpua.S) 359 } 360 361 hcpua.S: 362 .globl app_load // --------------- void app_load (void * fun) called by kinit() 363 app_load: // call when we exit kinit() function to go to user code 364 mtc0 $4, $14 // put _start address in c0_EPC 365 li $26, 0x12 // define next status reg. value 366 mtc0 $26, $12 // UM <- 1, IE <- 0, EXL <- 1 367 la $29, __data_end // define new user stack pointer 368 eret 369 }}} 370 Où est définit `_start` ? À quoi sert `.globl app_load `? Quels sont les registres utilisés dans le code de `app_load `? Que savez-vous de l'usage de `$26 `? Quels sont les registres modifiés ? Expliquez pour chacun la valeur affectée. Que fait l'instruction `eret `? 371 {{{#!protected ------------------------------------------------------------------------------------ 372 '' 373 Il faut lire le code assembleur et expliquer ce qui s'y trouve : 353 374 - Il y a 3 registres affectés, dans l'ordre : 354 375 - Le registre système `$14` nommé `c0_epc`, il reçoit l'adresse `__crt0`, c'est-à-dire l'adresse de la fonction `__start()`.