Changes between Version 19 and Version 20 of Archi-1-TD10


Ignore:
Timestamp:
Nov 20, 2022, 3:32:34 PM (3 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TD10

    v19 v20  
    407407 19 extern volatile struct tty_s __tty_regs_map[NTTYS];
    408408}}}
    409   À quoi servent les mots clés `extern` et `volatile` ?\\Si `NTTYS` est une macro dont la valeur est `2`, quelle est l'adresse en mémoire `__tty_regs_map[1].read` ? (C10 annexe S23 et connaissance du C)
    410 {{{#!protected ------------------------------------------------------------------------------------
    411 ''
     409  Si `NTTYS` est une macro dont la valeur est `2`, quelle est l'adresse en mémoire `__tty_regs_map[1].read` ?\\À quoi servent les mots clés `extern` et `volatile` ? (C10 annexe S23 et connaissance du C)
     410{{{#!protected ------------------------------------------------------------------------------------
     411''
     412- `__tty_regs_map` est un tableau à 2 cases (puisque `NTTYS`=`2`).\\Chaque case est une structure de 4 entiers, donc `0x10` octets (16 octets).\\`read` est le troisième champ, c'est le troisième entier de la structure, donc en `+8` par rapport au début.\\En conséquence `__tty_regs_map[1].read` est en `0xd0200018`
    412413- `extern` : informe le compilateur que la variable définie existe ailleurs. Grâce à son type, le compilateur sait s'en servir.
    413414- `volatile` : informe le compilateur que la variable peut changer de valeur toute seule et que donc il doit toujours accéder en mémoire à chaque fois que le programme le demande. Il ne peut donc pas optimiser les accès mémoire en utilisant les registres.
    414 - `__tty_regs_map` est un tableau à 2 cases (puisque `NTTYS`=`2`).\\Chaque case est une structure de 4 entiers, donc `0x10` octets (16 octets).\\`read` est le troisième champ, c'est le troisième entier de la structure, donc en `+8` par rapport au début.\\En conséquence `__tty_regs_map[1].read` est en `0xd0200018`
    415415''
    416416}}}
     
    430430''
    431431}}}
    432 5. Vous avez appris à écrire des programmes assembleur, mais parfois il est plus simple, voire nécessaire, de mélanger le code C et le code assembleur. Dans l'exemple ci-dessous, nous voyons comment la fonction `syscall()` est écrite. Cette fonction utilise l'instruction `syscall`.\\Deux exemples d'usage de la fonction `syscall()` pris dans le fichier `tp2/4_libc/ulib/libc.c`
    433 {{{#!c
    434   1 int fprintf (int tty, char *fmt, ...)
    435   2 {
     4325. Vous avez appris à écrire des programmes assembleur, mais parfois il est plus simple, voire nécessaire, de mélanger le code C et le code assembleur. Dans l'exemple ci-dessous, nous voyons comment la fonction `syscall()` est écrite. Cette fonction utilise l'instruction `syscall`.\\Deux exemples d'usage de la fonction `syscall()` pris dans le fichier `tp2/4_libc/ulib/libc.c`.
     433{{{#!c
     434  1 int fprintf (int tty, char *fmt, ...) // tty est l'identifiant du terminal
     435  2 {                                     // fmt est la chaine format, suivie d'une liste d'arguments optionnelz
    436436  3     int res;
    437437  4     char buffer[PRINTF_MAX];
    438438  5     va_list ap;
    439   6     va_start (ap, fmt);
    440   7     res = vsnprintf(buffer, sizeof(buffer), fmt, ap);
    441   8     res = syscall (tty, (int)buffer, 0, 0, SYSCALL_TTY_PUTS);
     439  6     va_start (ap, fmt);                               // définit le dernier argument non-optionnel
     440  7     res = vsnprintf(buffer, sizeof(buffer), fmt, ap); // remplit le buffer avec la chaîne à afficher
     441  8     res = syscall (tty, (int)buffer, 0, 0, SYSCALL_TTY_PUTS);  // ←  appel système
    442442  9     va_end(ap);
    443443 10     return res;
     
    446446 13 void exit (int status)
    447447 14 {
    448  15     syscall( status, 0, 0, 0, SYSCALL_EXIT);        // never returns
     448 15     syscall( status, 0, 0, 0, SYSCALL_EXIT);                   // ← appel système
    449449 16 }
    450450}}}
     
    452452 Le code de cette fonction est dans le fichier `tp2/4_libc/ulib/crt0.c`
    453453{{{#!c
    454   1 //int syscall (int a0, int a1, int a2, int a3, int syscall_code)
     454  1 // int syscall (int a0, int a1, int a2, int a3, int syscall_code)
    455455  2 __asm__ (
    456456  3 ".globl syscall     \n"         
     
    473473- 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.
    474474- Le noyau attend le numéro de service dans `$2`. Or le numéro du service est le 5e argument de la fonction `syscall()`. La ligne 5 permet d'aller le chercher dans la pile.
    475 - oui, ce code de la fonction `syscall()` qui fait appel à l'instruction `syscall` aurait pu être mis dans un fichier en assembleur, mais cela aurait demandé d'avoir un fichier de plus, pour une seule fonction. Dans une version plus évoluée du système, il y aura un d'autres fonctions assembleur, alors on créera un fichier assembleur pour les réunir.
    476 ''
    477 }}}
     475- oui, ce code de la fonction `syscall()` qui fait appel à l'instruction `syscall` aurait pu être mis dans un fichier en assembleur, mais cela aurait demandé d'avoir un fichier de plus, pour une seule fonction. Dans une version plus évoluée du système, il y aura d'autres fonctions assembleur, alors on créera un fichier assembleur pour les réunir.
     476''
     477}}}
     478
    478479
    479480
     
    491492
    492493
    493 1. Rappelez à quoi sert un Makefile?
     4941. Rappelez à quoi sert un Makefile? 
    494495{{{#!protected ------------------------------------------------------------------------------------
    495496''