TP et projets#
Architecture des ordinateurs et systèmes d'exploitation
TP Sous le capot#
programmer un processeur-jouet, puis piloter un vrai Linux en ligne de commande
Durée : 2 à 3 h (une séance par partie) · En binôme, sur machine
But du TP
Deux couches du « mille-feuille » du cours, à pratiquer sur machine. Partie A : écrire de vrais programmes pour le Little Man Computer (LMC), le processeur-modèle du cours, et les regarder s’exécuter instruction par instruction — calculs, tests, boucles. Partie B : dans un vrai Linux qui tourne dans le navigateur, construire une arborescence, manipuler des fichiers, puis mettre à l’épreuve les droits d’accès avec deux utilisateurs. Produits finaux : une collection de programmes LMC qui marchent, et un tableau « qui peut faire quoi » établi par l’expérience.
Consignes
-
Rien à installer. Gardez sous les yeux le jeu d’instructions LMC et le tableau des commandes du cours.
-
Partie A :
peterhigginson.co.uk/lmc/. On tape le programme dans la zone de gauche, on clique sur Submit (ou Assemble into RAM), puis Run (ou Step pour avancer d’une instruction). Quand la machine attend une entrée, on tape le nombre dans la case Input puis Entrée. Les boutons<<et>>règlent la vitesse. -
Partie B :
bellard.org/jslinux/, ligne x86 – Alpine Linux 3.12.0 – Console (comme dans l’activité « Perdu dans le terminal »). Recharger la page remet tout à zéro : notez vos commandes au fur et à mesure. -
▶ À faire sur machine. Pour chaque programme écrit, recopier le code final et les tests effectués (sur le cahier ou dans un fichier texte). Niveau : ★ échauffement, ★★ classique (niveau bac), ★★★ défi ; les coups de pouce et les corrigés se déplient sous chaque exercice.
-
Usage de l’IA, indiqué sur chaque exercice : aucune ; en appui (déboguer, reformuler, vérifier ; la réponse finale est écrite et comprise par vous) ; l’exercice s’appuie sur une réponse d’IA. Voir la charte d’usage de l’IA.
Partie A — Programmer le Little Man Computer#
★ Exercice 1 — Prise en main : la somme, vue de l’intérieur #
▶
Taper le programme du cours (avec des étiquettes, le simulateur choisit lui-même les adresses), l’assembler, puis l’exécuter pas à pas avec les entrées 5 puis 3.
INP
STA a
INP
STA b
LDA a
ADD b
OUT
HLT
a DAT
b DAT
-
Après l’assemblage, quels nombres apparaissent dans les cases 00 à 09 de la mémoire (RAM) ? Recopier-les.
-
En comparant au programme, retrouver le code de chaque instruction :
INP\(\to\) …,STA\(\to\) 3 …,LDA\(\to\) …,ADD\(\to\) …,OUT\(\to\) …,HLT\(\to\) … Que signifient les deux derniers chiffres ? -
Pendant l’exécution pas à pas, observer le compteur de programme : de combien avance-t-il à chaque instruction ? Quelle est sa valeur quand la machine s’arrête ?
-
Quelle idée du modèle de von Neumann cette mémoire illustre-t-elle ?
Corrigé
Les programmes LMC ci-dessous utilisent les mêmes codes d’instructions que le simulateur de Peter Higginson. Les sorties de terminal de la partie B sont celles de JSLinux (Alpine Linux 3.12.0, console x86).
1. Un if : un calcul (souvent SUB) suivi d’un saut conditionnel BRZ ou BRP, et d’un BRA pour sauter par-dessus le bloc « sinon ». Une boucle while : une étiquette en haut, un test de sortie (BRZ/BRP vers fin) et un BRA qui remonte. 2. La mémoire ne contient que des nombres : les instructions sont codées (ADD 09 \(\to\) 109). Les mots sont pour les humains (l’assembleur), les nombres pour la machine (le langage machine). 3. Tableau complété :
| pour… | lire un fichier | modifier un fichier | créer/supprimer dans un répertoire |
|---|---|---|---|
| il faut le droit… | r |
w |
w (et x) |
| sur… | le fichier (et x sur les répertoires traversés) |
le fichier | le répertoire |
root est-il concerné ? |
non | non | non |
Seule exception observée : pour exécuter un fichier, même root a besoin qu’au moins un x soit présent (exercice 10).
1. Cases 00 à 09 : 901 308 901 309 508 109 902 000 000 000. 2. INP \(\to\) 901, STA \(\to\) 3 …, LDA \(\to\) 5 …, ADD \(\to\) 1 …, OUT \(\to\) 902, HLT \(\to\) 000. Les deux derniers chiffres sont l’adresse de la case visée (a est en 08, b en 09). 3. Le compteur de programme avance de 1 à chaque instruction (il est incrémenté au moment où l’instruction est cherchée) ; à l’arrêt, il vaut 08 : l’instruction HLT (case 07) a déjà été lue. 4. Le programme est fait de nombres rangés dans la même mémoire que les données (les cases 08 et 09 contiennent les données, les cases 00 à 07 le programme) : c’est l’idée clé de von Neumann.
★ Exercice 2 — Le programme mystère #
Voici le contenu des cases 00 à 09 d’une mémoire, sans le programme assembleur : 901 309 901 109 309 109 902 000 000 000.
On sait aussi que SUB a pour code 2 …, BRA 6 …, BRZ 7 … et BRP 8 ….
-
« Désassembler » : réécrire ce programme en assembleur, une instruction par case.
-
Dérouler à la main pour les entrées 5 puis 3. Que calcule ce programme ?
-
▶ Vérifier de deux façons : taper votre version assembleur dans le simulateur et contrôler qu’après l’assemblage la RAM contient exactement les nombres de l’énoncé ; puis l’exécuter avec 5 et 3.
Corrigé
00 INP
01 STA 09
02 INP
03 ADD 09
04 STA 09
05 ADD 09
06 OUT
07 HLT
Déroulé pour 5 puis 3 : ACC \(=5\), case 09 \(=5\) ; ACC \(=3\) ; ACC \(=3+5=8\) ; case 09 \(=8\) ; ACC \(=8+8=16\) ; sortie 16.
Le programme calcule \(2 \times (a + b)\).
Assemblé, ce code redonne exactement les nombres de l’énoncé (les cases 08 et 09 restent à 000 avant l’exécution).
★★ Exercice 3 — L’écart entre deux nombres #
▶
Écrire un programme qui lit deux nombres \(a\) et \(b\) et affiche leur écart (la différence du plus grand moins le plus petit) : 2 et 7 donnent 5 ; 7 et 2 donnent 5 aussi. Le tester sur ces deux cas, puis avec deux nombres égaux.
Coup de pouce
Calculer d’abord b - a : si le résultat est positif ou nul (BRP), c’est la réponse ; sinon, recalculer dans l’autre sens a - b.
Corrigé
INP
STA a
INP
STA b
SUB a
BRP fin
LDA a
SUB b
fin OUT
HLT
a DAT
b DAT
Tests : (2, 7) \(\to\) 5 ; (7, 2) \(\to\) 5 ; (4, 4) \(\to\) 0.
Après SUB a, l’accumulateur contient \(b - a\). S’il est positif ou nul, c’est l’écart et l’on saute directement à OUT ; sinon on recalcule \(a - b\). C’est un if … else : BRP joue le rôle du test.
★★ Exercice 4 — Le compte à rebours #
▶
Écrire un programme qui lit un nombre \(n\) puis affiche \(n\), \(n-1\), …, \(1\), \(0\) et s’arrête. Le tester avec 3 (sorties : 3, 2, 1, 0), puis avec 0.
-
Quelle instruction permet de revenir en arrière dans le programme ? Laquelle permet d’en sortir ?
-
Il faut retirer 1 à chaque tour : où trouver ce 1 ? (Indice :
DATpeut recevoir une valeur initiale, par exempleun DAT 1.) -
Que se passerait-il si l’on oubliait le test d’arrêt ? Ne pas essayer longtemps : bouton Stop.
Coup de pouce
Une boucle en LMC : une étiquette sur la première instruction du corps (boucle OUT), un test qui saute vers fin quand l’accumulateur vaut 0 (BRZ fin), et un saut inconditionnel BRA boucle en bas du corps.
Corrigé
INP
boucle OUT
BRZ fin
SUB un
BRA boucle
fin HLT
un DAT 1
Tests : 3 \(\to\) 3, 2, 1, 0 ; 0 \(\to\) 0.
1. BRA boucle revient en arrière ; BRZ fin fait sortir quand ACC vaut 0. 2. Dans une case initialisée par un DAT 1. 3. Sans BRZ, la boucle ne s’arrête plus d’elle-même : le programme affiche des nombres négatifs indéfiniment (il faut l’arrêter).
Autre solution correcte : ranger \(n\) dans une case et faire LDA/SUB/STA à chaque tour (plus long mais correct).
★★ Exercice 5 — La multiplication sans multiplier #
▶
Le LMC ne sait pas multiplier. Mais \(a \times b\), c’est \(a + a + \dots + a\) (\(b\) fois).
-
Écrire un programme qui lit \(a\) puis \(b\) et affiche \(a \times b\), en ajoutant \(a\) à un résultat
res(initialisé à 0) et en décrémentant \(b\) à chaque tour, jusqu’à ce que \(b\) vaille 0. Le tester : \(6 \times 7\), \(5 \times 0\), \(0 \times 5\). -
Le corps de la boucle compte 8 instructions. Combien d’instructions environ la machine exécute-t-elle pour \(3 \times 200\) ? Et pour \(200 \times 3\) ? Comment rendre le programme plus rapide dans le premier cas ?
Coup de pouce
Cases à prévoir : a DAT, b DAT, res DAT 0, un DAT 1. Le corps de boucle : charger b ; s’il vaut 0, aller à fin ; sinon b \(\leftarrow\) b \(-\) 1, puis res \(\leftarrow\) res \(+\) a.
Corrigé
INP
STA a
INP
STA b
boucle LDA b
BRZ fin
SUB un
STA b
LDA res
ADD a
STA res
BRA boucle
fin LDA res
OUT
HLT
a DAT
b DAT
res DAT 0
un DAT 1
1. Tests : \(6 \times 7 \to 42\) ; \(5 \times 0 \to 0\) ; \(0 \times 5 \to 0\).
2. La machine exécute \(8b + 9\) instructions : 4 pour les entrées, 8 par tour de boucle, 2 pour le dernier test, 3 pour finir. Pour \(3 \times 200\) : 1 609 instructions ; pour \(200 \times 3\) : 33 seulement. Pour aller plus vite, il faut boucler sur le plus petit des deux nombres : comparer \(a\) et \(b\) au début (SUB puis BRP) et les échanger si besoin.
Même résultat, coût très différent : c’est déjà une question d’algorithmique.
★★ Exercice 6 — Le plus grand de trois #
▶
L’exercice 8 (« Le plus grand des deux ») de la rubrique Exercices de ce chapitre donne un programme qui affiche le plus grand de deux nombres. Écrire un programme qui lit trois nombres et affiche le plus grand. Le tester avec au moins quatre jeux d’entrées bien choisis (le maximum en 1re, 2e, 3e position ; des nombres égaux).
Coup de pouce
Appliquer l’invariant du champion : ranger le premier nombre dans une case max ; pour chacun des deux autres, calculer nombre - max ; si c’est positif ou nul (BRP), ce nombre devient le nouveau max.
Corrigé
INP
STA a
INP
STA b
INP
STA c
LDA a
STA max
LDA b
SUB max
BRP prendb
BRA testc
prendb LDA b
STA max
testc LDA c
SUB max
BRP prendc
BRA fin
prendc LDA c
STA max
fin LDA max
OUT
HLT
a DAT
b DAT
c DAT
max DAT
Tests : (9, 4, 7) \(\to\) 9 ; (4, 9, 7) \(\to\) 9 ; (4, 7, 9) \(\to\) 9 ; (7, 7, 2) \(\to\) 7. Le programme renvoie le bon maximum pour chacun des 125 triplets formés avec 0, 1, 4, 7, 9.
C’est l’invariant du champion du chapitre Algorithmique : le parcours séquentiel : max contient le plus grand nombre vu jusque-là.
Erreur fréquente : oublier BRA testc (ou BRA fin) ; la machine « tombe » alors dans le bloc suivant et prend toujours b (ou c).
★★★ Exercice 7 — Division euclidienne #
▶
Écrire un programme qui lit \(a\) puis \(b\) (avec \(b > 0\)) et affiche le quotient puis le reste de la division euclidienne de \(a\) par \(b\), en retirant \(b\) à \(a\) autant de fois que possible. Tester : \(17\) et \(5\) (sorties 3 puis 2) ; \(15\) et \(5\) ; \(4\) et \(9\). Que se passe-t-il si \(b = 0\) ? Quel est l’équivalent Python de ce programme (avec une boucle while) ?
Corrigé
INP
STA a
INP
STA b
boucle LDA a
SUB b
BRP suite
BRA fin
suite STA a
LDA q
ADD un
STA q
BRA boucle
fin LDA q
OUT
LDA a
OUT
HLT
a DAT
b DAT
q DAT 0
un DAT 1
Tests : (17, 5) \(\to\) 3 puis 2 ; (15, 5) \(\to\) 3 puis 0 ; (4, 9) \(\to\) 0 puis 4. Le programme donne le bon quotient et le bon reste pour tous les \(a\) de 0 à 59 et \(b\) de 1 à 11.
Si \(b = 0\), a - b reste toujours positif : la boucle ne s’arrête jamais (q augmente sans fin). Un programme correct testerait \(b\) dès le départ.
Équivalent Python :
q = 0
while a >= b:
a = a - b
q = q + 1
print(q, a)
Partie B — Piloter Linux en ligne de commande#
Dans JSLinux, vous êtes connecté en tant qu’administrateur : l’invite se termine par # (et non par $). Rappels pratiques : la touche Tab complète les noms ; la flèche haut rappelle les commandes précédentes ; history les liste toutes. La commande man n’est pas installée ici : ls --help affiche l’aide d’une commande.
★ Exercice 8 — Où suis-je, qui suis-je ? #
▶
-
Taper
whoami,pwd, puisls -l. Qui êtes-vous ? Où êtes-vous ? Quel est le chemin absolu de votre répertoire personnel ? -
Pour
readme.txt, écrire les droits du propriétaire, du groupe et des autres. Qui en est le propriétaire ?
Corrigé
1. whoami affiche root ; pwd affiche /root (c’est le répertoire personnel de l’administrateur). 2. ls -l montre -rw-r--r-- 1 root root 151 … readme.txt : fichier ordinaire, propriétaire root en lecture-écriture, groupe et autres en lecture seule.
★★ Exercice 9 — Construire l’arborescence du club #
▶
On veut obtenir, dans le répertoire personnel, l’arborescence suivante :
club
|-- archives
|-- docs
| |-- annonce.txt
|-- projets
|-- jeu
|-- site
-
Écrire, avant de les taper, les commandes qui créent les répertoires (depuis le répertoire personnel, en entrant dans
club). -
Pour créer un fichier qui contient du texte, on peut rediriger l’affichage d’
echovers un fichier :echo ’Reunion jeudi 13h’ > docs/annonce.txt. Le faire, puis afficher le contenu du fichier. -
Vérifier le résultat avec la commande
tree(qui dessine l’arbre), puis avecls -R.
Corrigé
|cd|
|mkdir club|
|cd club|
|mkdir archives docs projets|
|mkdir projets/jeu projets/site|
|echo 'Reunion jeudi 13h' > docs/annonce.txt|
|cat docs/annonce.txt|
Reunion jeudi 13h
|tree|
.
|-- archives
|-- docs
| `-- annonce.txt
`-- projets
|-- jeu
`-- site
5 directories, 1 file
(tree dessine l’arbre avec des traits continus ; ls -R liste le contenu de chaque répertoire, l’un après l’autre.)
★★ Exercice 10 — Un script et le droit x #
▶
-
Dans
club, créer un petit programme :echo ’echo Bonjour le club’ > bonjour.sh. Afficher ses droits avecls -l. -
Le lancer avec
./bonjour.sh. Quel message obtient-on ? Pourquoi ? -
Le lancer avec
sh bonjour.sh. Cette fois ça marche : quel programme est réellement exécuté, et de quel droit surbonjour.sha-t-il besoin ? -
Rendre le fichier exécutable par son propriétaire, vérifier avec
ls -l(qu’est-ce qui a changé ?), et relancer./bonjour.sh.
Corrigé
|echo 'echo Bonjour le club' > bonjour.sh|
|ls -l bonjour.sh|
-rw-r--r-- 1 root root 21 ... bonjour.sh
|./bonjour.sh|
sh: ./bonjour.sh: Permission denied
|sh bonjour.sh|
Bonjour le club
|chmod u+x bonjour.sh|
|ls -l bonjour.sh|
-rwxr--r-- 1 root root 21 ... bonjour.sh
|./bonjour.sh|
Bonjour le club
2. Le fichier n’a le droit x pour personne : le système refuse de l’exécuter, même pour root. 3. Avec sh bonjour.sh, c’est le programme sh (l’interpréteur de commandes) qui est exécuté ; il se contente de lire bonjour.sh, ce qui ne demande que le droit r. 4. Un x est apparu chez le propriétaire.
★★ Exercice 11 — Copier, déplacer, renommer, supprimer #
▶
Depuis club, prévoir sur le cahier l’arbre obtenu après la suite d’actions ci-dessous, puis écrire et exécuter les commandes, et comparer avec tree.
-
copier
annonce.txtdansarchives; -
renommer cette copie en
annonce_sept.txt; -
déplacer
bonjour.shdansprojets/jeu, puis le lancer depuisclubsans changer de répertoire ; -
supprimer le répertoire
projets/siteet tout son contenu. Pourquoi faut-il être particulièrement prudent avec cette commande ?
Corrigé
|cp docs/annonce.txt archives/|
|mv archives/annonce.txt archives/annonce_sept.txt|
|mv bonjour.sh projets/jeu/|
|./projets/jeu/bonjour.sh|
Bonjour le club
|rm -r projets/site|
|tree|
.
|-- archives
| `-- annonce_sept.txt
|-- docs
| `-- annonce.txt
`-- projets
`-- jeu
`-- bonjour.sh
4 directories, 3 files
rm -r supprime définitivement un répertoire et tout ce qu’il contient, sans corbeille ni confirmation : une faute de frappe sur le nom peut effacer tout un travail.
★★ Exercice 12 — L’administrateur n’a pas de limites #
▶
Créer secret.txt contenant une ligne de texte, puis lui retirer tous les droits : chmod 000 secret.txt. Vérifier avec ls -l, puis essayer cat secret.txt. Que constate-t-on ? Expliquer, et en déduire pourquoi le cours conseille de ne pas travailler en permanence avec le compte root.
Corrigé
|echo 'code: 1234' > secret.txt|
|chmod 000 secret.txt|
|ls -l secret.txt|
---------- 1 root root 11 ... secret.txt
|cat secret.txt|
code: 1234
Personne n’a de droit sur le fichier… et pourtant root le lit : l’administrateur ignore les droits de lecture et d’écriture (seule l’exécution exige au moins un x, comme on l’a vu). Une erreur ou un programme malveillant lancé en root n’est donc arrêté par aucune protection : d’où le conseil de n’utiliser ce compte qu’en cas de besoin.
★★★ Exercice 13 — Mini-scénario : le dossier partagé #
▶
Pour voir les droits à l’œuvre, il faut un deuxième utilisateur. En tant que root, taper :
|adduser -D lea|
|mkdir /tmp/partage|
|cd /tmp/partage|
|echo 'Sortie au musee le 12' > annonce.txt|
|echo 'Lea 15, Tom 12' > notes.txt|
|chmod o-r notes.txt|
|ls -l|
(adduser -D lea crée un compte lea sans mot de passe, possible seulement pour l’administrateur.)
1. Prévoir, puis vérifier. Recopier le tableau et le compléter avant de passer sur le compte de Léa avec su lea (l’invite se termine alors par $). Puis taper chaque commande et noter le résultat réel. On revient au compte root avec exit.
commande tapée par lea, dans /tmp/partage |
prévision | résultat |
|---|---|---|
cat annonce.txt |
||
cat notes.txt |
||
echo ’Lea vient’ >> annonce.txt (ajoute une ligne) |
||
touch essai.txt |
||
cat /root/club/docs/annonce.txt |
||
cd ; touch essai.txt (dans son répertoire personnel) |
2. Changer les règles. Revenu en root, écrire les commandes chmod qui : (a) retirent aux « autres » le droit de lire et de traverser /root/club ; (b) permettent aux « autres » de modifier annonce.txt ; (c) permettent au groupe et aux autres de lire notes.txt. Repasser sur le compte de Léa et refaire les cinq premières lignes du tableau.
3. L’énigme. Léa peut maintenant modifier annonce.txt. Peut-elle le supprimer avec rm ? Essayer. En regardant les droits du répertoire /tmp/partage (ls -ld /tmp/partage), proposer une explication.
Coup de pouce
Pour un répertoire, r permet d’en lister le contenu, x d’y entrer ou de le traverser, et w d’y créer ou d’y supprimer des fichiers.
Corrigé
1. Résultats obtenus (notes.txt est en -rw-r-----, annonce.txt en -rw-r--r--, /tmp/partage en drwxr-xr-x, tous à root) :
commande (lea) |
résultat |
|---|---|
cat annonce.txt |
Sortie au musee le 12 : les autres ont r |
cat notes.txt |
cat: can’t open ’notes.txt’: Permission denied |
echo ’Lea vient’ >> annonce.txt |
ash: can’t create annonce.txt: Permission denied (pas de w) |
touch essai.txt |
touch: essai.txt: Permission denied (pas de w sur le répertoire) |
cat /root/club/docs/annonce.txt |
Reunion jeudi 13h : r sur le fichier, x sur les répertoires |
cd ; touch essai.txt |
réussit : /home/lea appartient à lea |
2.
|chmod o-rx /root/club|
|chmod o+w /tmp/partage/annonce.txt|
|chmod go+r /tmp/partage/notes.txt|
Pour lea ensuite : annonce.txt est toujours lisible, et maintenant modifiable (la ligne Lea vient s’ajoute) ; notes.txt devient lisible (Lea 15, Tom 12) ; touch essai.txt est toujours refusé ; cat /root/club/docs/annonce.txt est désormais refusé (Permission denied) : sans le droit x sur club, on ne peut plus traverser ce répertoire, même si le fichier lui-même est lisible.
3. rm /tmp/partage/annonce.txt donne rm: can’t remove ’/tmp/partage/annonce.txt’: Permission denied. Supprimer un fichier, c’est modifier le répertoire qui le contient (retirer son nom de la liste) : il faut le droit w sur /tmp/partage, qui est en drwxr-xr-x. Le droit w sur le fichier permet d’en changer le contenu, pas de le faire disparaître.
Bilan#
Exercice 14 — Ce que j’ai appris #
-
Dans le LMC, comment réalise-t-on un
if? une bouclewhile? Citer les instructions utilisées. -
Pourquoi le simulateur affiche-t-il des nombres dans la mémoire, et pas des mots comme
ADD? -
Recopier sur le cahier et compléter le tableau « qui peut faire quoi » à partir de vos expériences :
pour… lire un fichier modifier un fichier créer/supprimer dans un répertoire il faut le droit… sur… rootest-il concerné ?