J'ai terminé de lire ton tutoriel et je dois dire que, même en connaissant fort bien tout ce dont tu parles, je ne le trouve pas clair du tout. Le principal reproche que je ferais est que, à mon avis, tu as organisé la présentation à l'envers : tu suis l'ordre des opérations effectuées lors d'une compilation, alors que tu devrais suivre l'ordre des dépendances de conception, qui va en sens inverse.
L'objectif ultime d'une compilation, c'est qu'un programme soit exécuté. Il faudrait donc commencer par présenter l'exécution, comment elle fonctionne, la différence programme / bibliothèque (pas librairie) partagée, les différentes solutions proposées par les OS, et ce que ce fonctionnement pose comme contraintes sur le format des fichiers exécutables. Ensuite, tu présenterais l'édition de liens, son utilité, comment il s'adapte aux contraintes posées par la phase d'exécution, notamment en faisant subir un traitement différent aux bibliothèques et aux programmes, et ce que son propre fonctionnement pose comme contraintes sur le format des fichiers objets et bibliothèques statiques. Puis, dans la suite logique, tu fais la même chose avec le logiciel d'assemblage, qui doit composer avec les contraintes imposées par l'éditeur de lien, etc.
Ensuite, je te trouve très vague dans ton explication de la traduction d'une ligne de code assembleur en code machine : en résumé, tu dis qu'il y a plusieurs éléments et que chaque élément est traduit, ce qui s'apparente à une lapalissade, mais étalée sur 40 lignes. Je pense qu'il y aurait un intérêt à montrer précisément et avec des exemples tirés de plusieurs ISA différentes comment l'assembleur devient du code machine, ce qui est loin d'être aussi simple qu'il y paraît. En particulier, le code machine x86 est particulièrement crade, et cela me semble intéressant de montrer le vrai défi que représente sa génération depuis de l'assembleur compréhensible.