Architecture Logicielle et matérielle Cours 6b : Programmation LC3, routines et assemblage D’après les transparents de N. Louvet (univ Lyon1) Laure Gonnord http://laure.gonnord.org/pro/teaching/ [email protected] Licence d’info - Université Lyon 1 - FST Introduction Dans le cours de programmation LC3-1 (Cours6a), on a vu : Les instructions de calcul Les instructions de contrôle Les instructions d’accès et écriture mémoire (chargement/déchargement) I Il manque une façon de réaliser les appels de fonctions. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 2 / 37 Les routines et la pile 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 3 / 37 Les routines et la pile Les routines 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 4 / 37 Les routines et la pile Les routines Les routines En assembleur, une routine est juste une portion de code exécutable : l’adresse de la première instruction de cette portion de code est connue, et marquée par un label ; on peut effectuer un saut vers cette portion de code (instruction JSR), qui constitue un appel à la routine ; à la fin de l’exécution de la routine, une instruction de retour (RET) est exécutée pour que le PC passe à l’adresse suivant l’appel de la routine. Une routine correspond à une fonction dans un langage de haut niveau. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 5 / 37 Les routines et la pile Les routines JSR Lorsqu’une routine est appelée, il faut mémoriser l’adresse à laquelle doit revenir s’exécuter le programme à la fin de la routine. JSR stocke l’adresse de retour dans R7, puis effectue un branchement à l’adresse passée comme opérande. syntaxe : JSR label action : R7 <- PC ; PC <- PC + SEXT(PCoffset11) on a : -10246Sext(Offset11)61023. si adI est l’adresse de l’instruction JSR, l’adresse de branchement est : adM = adI+1+Sext(PCOffset11), avec adI − 1023 6 adM 6 adI + 1024. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 6 / 37 Les routines et la pile Les routines RET Lors de l’appel d’une routine, l’adresse de retour est stockée dans R7 par JSR. L’instruction RET permet de retourner à la routine appelante, par un saut à l’adresse contenue dans R7. syntaxe : RET action : PC <- R7 Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 7 / 37 Les routines et la pile Les routines Exemple Dans le programme, on fera par exemple appel à la routine sub : ... JSR sub ... ; Adresse de l'instr. suivante dans R7 La dernière instruction de la routine sera RET : ; routine sub sub: ... ... RET Laure Gonnord (L2/FST/Univ Lyon1) ; retour au programme principal ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 8 / 37 Les routines et la pile Un exemple de routine 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 9 / 37 Les routines et la pile Un exemple de routine Ex : longueur de chaîne - Rappel .ORIG x3000 LEA R0,string AND R1,R1,0 loop: LDR R2,R0,0 BRz end ADD R0,R0,1 ADD R1,R1,1 BR loop end: ST R1,res HALT ; Chaine constante string: .STRINGZ "Hello res: .BLKW #1 .END Laure Gonnord (L2/FST/Univ Lyon1) ; ; ; ; ; ; Initialisation du pointeur R0 Le compteur R1 est initialisé à 0 Chargement dans R2 du caractere pointé par R0 Test de sortie de boucle Incrémentation du pointeur Incrémentation du compteur World" ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 10 / 37 Les routines et la pile Un exemple de routine Longueur de chaîne - routine 1/2 Spec : écrire strlen : L’adresse de la chaîne est placée dans R0. Le résultat sera stocké dans R0 .ORIG x3000 ; Programme principal LEA R0,chaine1 ; Chargement dans R0 de l'adresse de la chaîne JSR strlen ; Appel de la routine ST R0,lg1 HALT ; Données chaine1: .STRINGZ "Hello World" lg1: .BLKW #1 Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 11 / 37 Les routines et la pile Un exemple de routine Longueur de chaîne - routine 2/2 ; Routine pour calculer la longueur d'une chaîne terminée par '\0'. ; paramètre d'entrée : R0 adresse de la chaîne ; paramètre de sortie : R0 longueur de la chaîne strlen: AND R1,R1,0 loop: LDR R2,R0,0 BRz fini ADD R0,R0,1 ADD R1,R1,1 BR loop fini: ADD R0,R1,0 RET ; R0 <- R1 ; Retour par JMP R7 .END ; fin prog complet. Laure Gonnord (L2/FST/Univ Lyon1) ; ; ; ; ; Mise à 0 du compteur : c = 0 Chargement dans R2 du caractère d'@ R0 Test de fin de chaîne Incrémentation du pointeur Incrémentation du compteur ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 12 / 37 Les routines et la pile Mise en place d’une pile d’exécution 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 13 / 37 Les routines et la pile Mise en place d’une pile d’exécution Mise en place d’une pile d’exécution Dans une routine appelant une autre routine, il est important de pouvoir sauvegarder les registres dont on souhaite retrouver le contenu après l’exécution de la routine appelée. Notamment, si une routine doit en appeler une autre, elle doit forcément préserver R7 qui contient son adresse de retour (et qui sera écrasé par JSR). Une méthode consiste à mettre en place une pile d’exécution : cela permet notamment de gérer facilement des appels récursifs de routines. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 14 / 37 Les routines et la pile Mise en place d’une pile d’exécution Solution LC3 : Registre R6 réservé R6 est initialisé à un adresse de « fond de pile » (stackend). Pendant toute l’exécution du programme, R6 donne l’adresse de la dernière valeur mise sur la pile. La pile croît dans le sens des adresses décroissantes. R0 R1 R6 R7 x0000 ins1 ins2 x30FE x3000 x3001 x30FF 1111111 0000000 x3100 0000000 1111111 stackend: xFFFF Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 15 / 37 Les routines et la pile Mise en place d’une pile d’exécution Solution LC3 - Mise en place (programme) .ORIG x3000 ; Programme principal main: LD R6,spinit ... HALT ; Gestion de la spinit: .FILL .BLKW stackend: .BLKW ; on initialise le pointeur de pile pile stackend #15 #1 ; adresse du fond de la pile .END Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 16 / 37 Les routines et la pile Mise en place d’une pile d’exécution Solution LC3 - Opérations empiler/dépiler Empilement d’un registre Ri : ADD R6,R6,-1 ; déplacement du sommet de pile STR Ri,R6,0 ; rangement de la valeur Dépilement du sommet de pile dans un registre Ri : LDR Ri,R6,0 ADD R6,R6,1 Laure Gonnord (L2/FST/Univ Lyon1) ; récupération de la valeur ; restauration du sommet de pile ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 17 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 18 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile Un (dummy) exemple utilisant la pile 1 On veut écrire un programme pour calculer la somme des entiers de 1 à n. Ce serait trop simple avec une boucle, on va le faire avec des appels récursifs ! En C, en supposant n > 0, on pourrait le faire via une fonction du style : i n t sum ( i n t n ) { i f ( n==0) r e t u r n ( 0 ) ; else r e t u r n ( sum ( n−1)+n ) ; } Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 19 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile Un (dummy) exemple utilisant la pile 2 Dans notre implantation sur le LC3, on va supposer pour simplifier que : R1 servira de paramètre d’entrée, R0 de paramètre de retour ; les registres R1 et R7 seront sauvegardés par la routine sum au début de chaque appel, et restaurés à la fin de chaque appel. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 20 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile Dummy exemple 3 - pseudo code On va traduire le pseudocode suivant : routine sum(R1) { push(R7); push(R1); if(R1 == 0) { R0 <- 0; } else { R1 <- R1 - 1; call sum(R1); R1 <- top(); R0 <- R0 + R1; } R1 <- pop(); R7 <- pop(); return; } Laure Gonnord (L2/FST/Univ Lyon1) // Sauvegarde de R7 sur la pile // Sauvegarde de R1 sur la pile // On prépare le paramètre de l'appel récursif // Appel récursif // R1 reprend sa valeur depuis le sommet de pile // Restauration de R1 depuis la pile // Restauration de R7 depuis la pile // Resultat retourné via R0 ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 21 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile Dummy exemple 4 - Main .ORIG x3000 ; Programme principal main: LD R6,spinit ; on initialise le pointeur de pile LD R1,n ; on initialise R1 avant l'appel à la routine su JSR sum ; appel à la routine sum ST R0,r ; on stocke le résultat à l'adresse r HALT ;; ICI ROUTINE SUM ; Données n: .FILL #5 r: .BLKW #1 ; Gestion de la spinit: .FILL .BLKW stackend: .BLKW pile stackend #15 #1 ; adresse du fond de la pile Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 22 / 37 Les routines et la pile Un exemple de routine récursive utilisant la pile Dummy example 5 : routine sum ; Routine sum. Paramètre d'entrée : R1 Paramètre de sortie : R0 sum: ADD R6,R6,#-1 ; STR R7,R6,#0 ; On sauvegarde l'adresse de retour R7. ADD R6,R6,#-1 ; STR R1,R6,#0 ; On sauvegarde l'adresse de retour R1. if: ADD R1,R1,#0 ; Mise à jour du PSR d'après R1. BRnp else ; Si R1 != 0, branchement sur le bloc else AND R0,R0,#0 ; Si R1 == 0, la valeur de retour est 0, BR endif ; et on ne fait pas d'appel récursif. else: ADD R1,R1,#-1 ; Dans le cas R1 == 0, on prépare l'appel rec. JSR sum ; Appel récursif. LDR R1,R6,#0 ; On récupère la valeur de R1 avant l'appel rec. ADD R0,R0,R1 ; On calcule le résultat dans R0 (sortie). endif: LDR R1,R6,#0 ; On restaure le registre R1. ADD R6,R6,#1 ; LDR R7,R6,#0 ; On restaure le registre R7. ADD R6,R6,#1 ; RET ; On retourne à l'appelant Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 23 / 37 Quelques notions sur l’assemblage 1 Les routines et la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 24 / 37 Quelques notions sur l’assemblage Plan 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 25 / 37 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 26 / 37 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Comment se déroule l’assemblage ? L’assemblage consiste à traduire un programme écrit en langage d’assemblage en un programme écrit en langage machine, directement exécutable par le processeur : un tel programme est appelé aussi code objet. fichier source langage d’assemblage .asm assembleur code objet langage machine .obj Un code objet contient un préambule (destiné au système d’exploitation), contenant en particulier l’adresse à laquelle il doit être chargé. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 27 / 37 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Assembleur : Algo À partir du début de programme, ligne par ligne : Il calcule l’adresse de cette ligne en mémoire centrale. Si cette ligne est marquée par un label, il stocke l’association entre ce label et l’adresse courante dans un tableau associatif. Si la ligne est dédiée à la réservation de l’espace d’une donnée (directives .FILL, .BLKW. . . ), l’assembleur saute les adresses mémoire correspondantes. Si la ligne est occupée par une instruction, l’assembleur traduit l’instruction. Il passe à la ligne suivante. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 28 / 37 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Assembleur : Algo - 2 Traduction d’instruction avec label (BR par exemple) : Soit ce label est déjà présent dans le tableau associatif dédié : le label a été déclaré avant, au dessus de l’instruction ; l’adresse du label est inférieure à l’adresse de l’instruction. On parle d’une référence-arrière, l’assembleur peut traduire l’instruction. Soit ce label n’est pas encore présent dans le tableau associatif : le label est déclaré après, au dessous de l’instruction ; l’adresse du label est supérieure à l’adresse de l’instruction. On parle de référence-avant, l’assembleur ne peut pas traduire l’instruction. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 29 / 37 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Assembleur : Algo - 3 On ne peut pas traduire la référence avant, d’où un algo à deux passes : Passe 1 : toutes les adresses sont calculées, toutes les instructions avec référence-arrière traduites, et toutes les instructions avec référence-avant laissées de côté. Passe 2 : traduction de toutes les instructions avec référence-avant. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 30 / 37 Quelques notions sur l’assemblage Un exemple 1 Les routines et la pile Les routines Un exemple de routine Mise en place d’une pile d’exécution Un exemple de routine récursive utilisant la pile 2 Quelques notions sur l’assemblage Comment se déroule l’assemblage ? Un exemple 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 31 / 37 Quelques notions sur l’assemblage Un exemple Exemple assemblage : code “source” .ORIG x3000 ; adresse de début de programme ;############ DEBUT DU PROGRAMME ############ ; partie dédiée au code loop: GETC ; lit un caractère au clavier, TRAP x20 OUT ; affiche le caractère lu à l'écran LD R1,cmpzero ; charge le complément à 2 du code de '0' dans R1 ADD R0,R0,R1 ; on l'ajoute au caractère lu BRz break ; si le résultat est nul, saute à l'adresse break BR loop ; sinon, saute à l'adresse loop break: LEA R0,msg ; charge l'adresse de msg dans R0 PUTS ; affiche msg à l'écran, TRAP x22 HALT ; rend la main à l'OS, TRAPx00 ; partie dédiée aux données cmpzero: .FILL xFFD0 ; complément à 2 sur 16 bits du code de '0' msg: .STRINGZ "\nzero!\n" ;############ FIN DU PROGRAMME ############ .END Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 32 / 37 Quelques notions sur l’assemblage Un exemple Exemple assemblage : après la première passe loop: GETC OUT LD R1,cmpzero ADD R0,R0,R1 BRz break BR loop break: LEA R0,msg PUTS HALT cmpzero: .FILL xFFD0 msg: .STRINGZ "\nzero!\n" Laure Gonnord (L2/FST/Univ Lyon1) -> -> -> -> -> -> -> -> -> -> -> adresse x3000 x3001 x3002 x3003 x3004 x3005 x3006 x3007 x3008 x3009 x300A x300B x300C x300D x300E x300F x3010 x3011 contenu xF020 xF021 -???x1001 -???x0FFA -???xF022 xF025 xFFD0 x000A '\n' x007A 'z' x0065 'e' x0072 'r' x006F 'o' x0021 '!' x000A '\n' x0000 '\0' ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 33 / 37 Quelques notions sur l’assemblage Un exemple Exemple assemblage : après la deuxième passe loop: GETC OUT LD R1,cmpzero ADD R0,R0,R1 BRz break BR loop break: LEA R0,msg PUTS HALT cmpzero: .FILL xFFD0 msg: .STRINGZ "\nzero!\n" Laure Gonnord (L2/FST/Univ Lyon1) -> -> -> -> -> -> -> -> -> -> -> adresse x3000 x3001 x3002 x3003 x3004 x3005 x3006 x3007 x3008 x3009 x300A x300B x300C x300D x300E x300F x3010 x3011 contenu xF020 xF021 x2206 x1001 x0401 x0FFA xE003 xF022 xF025 xFFD0 x000A '\n' x007A 'z' x0065 'e' x0072 'r' x006F 'o' x0021 '!' x000A '\n' x0000 '\0' ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 34 / 37 Quelques notions sur l’assemblage Un exemple Exemple assemblage : code objet Le code-objet généré contiendra simplement l’adresse de début de programme, puis la concaténation des mots-machine générés : 3000F020F021220610010401 0FFAE003F022F025FFD0000A 007A00650072006F0021000A 0000 Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 35 / 37 Conclusion 1 Les routines et la pile 2 Quelques notions sur l’assemblage 3 Conclusion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 36 / 37 Conclusion Conclusion Nous avons vu : un exemple de langage d’assemblage, quelques principes de fonctionnement d’un assembleur, comment sont mis en place les appels de routines et la pile. L’étape suivante serait de voir comment un compilateur génère du code en langage d’assemblage à partir d’un programme dans un langage de haut niveau : source du programme langage C Laure Gonnord (L2/FST/Univ Lyon1) compilateur programme traduit en langage d’assemblage assembleur langage machine code objet ArchiL2 (LIF6) Cours 06b : Programmation LC3 2/2 2014 37 / 37