Architecture Logicielle et matérielle Cours 6 : Programmation LC3 (sans routine) 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 Le LC-3 est un processeur développé dans un but pédagogique par Yale N. Patt et J. Patel dans [Introduction to Computing Systems : From Bits and Gates to C and Beyond, McGraw-Hill, 2004]. Des sources et exécutables sont disponibles à l’adresse : http://highered.mcgraw-hill.com/sites/0072467509/ Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 2 / 34 Intro 2/2 Nous allons nous baser sur le LC-3 pour illustrer les points suivants : Comment programme-t-on en assembleur ? Comment mettre en place des routines ? Comment mettre en place une pile d’exécution de programme ? Que doit faire un assembleur ? Ce cours est inspiré de celui d’Olivier Carton (Université Paris Diderot - Paris 7), disponible à l’adresse : http://www.liafa.jussieu.fr/~carton Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 3 / 34 Introduction à l’architecture du LC-3 1 Introduction à l’architecture du LC-3 2 Les instructions du LC3 Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 4 / 34 Introduction à l’architecture du LC-3 La mémoire centrale et les registres du LC-3 La mémoire du LC-3 est organisée par mots de 16 bits, avec un adressage également de 16 bits. La mémoire du LC-3 est donc formée de 216 mots de 16 bits, c’est-à-dire 128 Kio avec des adresses de (0000)H à (FFFF)H . 8 registres généraux 16 bits : R0,. . . ,R7. Toutefois, R6 : gestion de la pile d’exécution, R7 : stockage de l’adresse de retour d’un appel de fonction (RET). quelques registres spécifiques 16 bits : PC (Program Counter), IR (Instruction Register) PSR (Program Status Register) plusieurs drapeaux. quelques autres. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 5 / 34 Introduction à l’architecture du LC-3 Registre PSR Les bits N,Z,P du PSR indiquent si la dernière valeur placée dans un registre général est négative strictement (N), zéro (Z) ou positive strictement (P). I On s’en sert pour les tests Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 6 / 34 Introduction à l’architecture du LC-3 Exemple : afficher les entiers de 9 à 0 - 1/5 print("Affichage des entiers de 9 à 0 :\n"); i <- 9; while(i >= 0) { print(i + '0'); i <- i - 1; } print("\nFin de l'affichage !\n"); Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 7 / 34 Introduction à l’architecture du LC-3 Exemple 2/5 : pseudo code + registres R0 pour l’affichage, R1 comme compteur et R2 pour ’0’ : print("Affichage des entiers de 9 à 0 :\n"); R2 <- '0'; R1 <- 9; while(R1 >= 0) { R0 <- R1 + '0'; print(R0); R1 <- R1 - 1; } print("\nFin de l'affichage !\n"); Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 8 / 34 Introduction à l’architecture du LC-3 Exemple 3/5 : schéma général de traduction boucle while : /* En peudo-code */ while(e cmp 0) { corps de boucle } ; En langage d'assemblage du LC3 loop: evaluation de e BR!cmp endloop ; condition de sortie de boucle corps de boucle BR loop ; branchement inconditionnel endloop: Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 9 / 34 Introduction à l’architecture du LC-3 Exemple 4/5 : application /* En peudo-code */ R1 <- 9; while(R1 >= 0) { R0 <- R1 + '0'; print(R0); R1 <- R1 - 1; } ; En langage d'assemblage du LC3 AND R1,R1,0 ; ADD R1,R1,9 ; R1 <- 9 loop: ADD R1,R1,0 ; pour forcer la maj du PSR BRn endloop ; si R1 < 0, on sort de la boucle ADD R0,R1,R2 ; R0 <- (code ascii du chiffre R1) OUT ; affiche le caractère dans R0 ADD R1,R1,-1 ; R1 <- R1-1, maj du PSR d'après R1 BR loop ; retour au début de boucle endloop: Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 10 / 34 Introduction à l’architecture du LC-3 Ex 5/5 : prog entier .ORIG x3000 ; adresse de début de programme ; partie dédiée au code LEA R0,msg0 ; charge l'adresse effective désignée par msg0 dans R0 PUTS ; affiche la chaine de caractères pointée par R0 (TRAP x22) LD R2,carzero ; charge '0' dans R2 AND R1,R1,0 ; ADD R1,R1,9 ; R1 <- 9 loop: BRn endloop ; si R1 < 0, alors on sort de la boucle ADD R0,R1,R2 ; R0 <- R1+'0' = (code ascii du chiffre R1) OUT ; affiche le caractère contenu dans R0 (TRAP x21) ADD R1,R1,-1 ; R1 <- R1-1, maj de NZP d'après R1 BR loop ; retour au début de boucle endloop: LEA R0,msg1 ; charge l'adresse effective désignée par msg0 dans R0 PUTS ; affiche la chaine de caractères pointée par R0 (TRAP x22) HALT ; termine le programme ; partie dédiée aux données carzero: .FILL x30 ; code ASCII du caractère '0' (48 en décimal) msg0: .STRINGZ "Affichage des entiers de 9 à 0 :\n" msg1: .STRINGZ "\nFin de l'affichage !\n" .END ; marque la fin du bloc de code Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 11 / 34 Introduction à l’architecture du LC-3 Forme générale d’un programme Un programme source écrit en langage d’assemblage est un fichier texte qui comporte une suite de lignes. Sur chaque ligne, on trouve : soit une instruction (ADD, LD, BR,. . . ) ; soit une macro (GETC, OUT,. . . ) ; soit une directive d’assemblage (.ORIG, .BLKW,. . . ) ; Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 12 / 34 Introduction à l’architecture du LC-3 Forme générale d’un programme : labels Une ligne peut être précédée par une étiquette pour référencer son adresse. .ORIG x3000 ; partie dédiée au code loop: GETC OUT LD R1,cmpzero ADD R0,R0,R1 ... ; partie dédiée aux données cmpzero: .FILL xFFD0 msg: .STRINGZ "\nzero!\n" .END Laure Gonnord (L2/FST/Univ Lyon1) ; directive pour le début de programme <- il s'agit d'un commentaire ; macro marquée par une étiquette ; macro ; instruction ; instruction ; directive ; directive ; directive marquant la fin du programme ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 13 / 34 Introduction à l’architecture du LC-3 Etiquettes ou labels L’assembleur permet d’utiliser des labels pour désigner des adresses. Un label est associé à une adresse et peut être utilisé par d’autres instructions. L’assembleur traduira ce label en une adresse effective lors de l’assemblage. Par exemple, l’étiquette label représente ci-dessous l’adresse où se trouve l’instruction ADD R6,R1,R2 : ... label: ADD R6,R1,R2 ... BRz label ... Laure Gonnord (L2/FST/Univ Lyon1) ; R6 <- R1 + R2 ; Branchement conditionnel à l'adresse label ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 14 / 34 Introduction à l’architecture du LC-3 2 types de constantes Les chaînes de caractères : directive .STRINGZ : elles sont délimitées par deux caractères " et implicitement terminées par le caractère nul. Les constantes entières écrites en hexadécimal sont précédées d’un x, en décimal elles sont précédées d’un # : opérandes immédiats des instructions paramètres des directives .ORIG, .FILL et .BLKW. Exemple : .ORIG x3000 AND R2,R1,#2 ADD R6,R5,#-1 .STRINGZ "Chaine" Laure Gonnord (L2/FST/Univ Lyon1) ; ; ; ; Constante Constante Constante Constante entière en base 16 entière en base 10 entière négative en base 10 chaîne de caractères ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 15 / 34 Introduction à l’architecture du LC-3 Directives d’assemblage .ORIG adresse : Spécifie l’adresse à laquelle doit commencer le bloc d’instructions qui suit. .END : Termine un bloc d’instructions. .FILL valeur : Réserve un mot de 16 bits et le remplit avec la valeur constante donnée en paramètre. .STRINGZ chaine : Réserve un nombre de mots égal à la longueur de la chaîne de caractères plus un caractère nul et y place la chaîne. .BLKW nombre : Cette directive réserve le nombre de mots de 16 bits passé en paramètre. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 16 / 34 Introduction à l’architecture du LC-3 Les interruptions prédéfinies : « appels système » L’instruction TRAP appelle un gestionnaire d’interruption mis en place par le petit système d’exploitation du LC-3 : il s’agit donc d’un appel système. Chaque appel système est identifié par une constante sur 8 bits. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 17 / 34 Introduction à l’architecture du LC-3 Macros pour les interruptions Dans l’assembleur du LC-3, on peut utiliser les macros suivantes pour effectuer des appels systèmes. instruction macro description TRAP x00 TRAP x20 HALT GETC termine un programme (rend la main à l’OS) TRAP x21 OUT écrit à l’écran le caractère ASCII placé dans l’octet de poids faible de R0 TRAP x22 PUTS écrit à l’écran la chaine de caractères pointée par R0 TRAP x23 IN lit au clavier un caractère ASCII, l’écrit à l’écran, et le place dans l’octet de poids faible de R0 Laure Gonnord (L2/FST/Univ Lyon1) lit au clavier un caractère ASCII et le place dans l’octet de poids faible de R0 ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 18 / 34 Les instructions du LC3 1 Introduction à l’architecture du LC-3 2 Les instructions du LC3 Les instructions de chargement et rangement Les instructions de branchement Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 19 / 34 Les instructions du LC3 Les instructions du LC-3 (redite, cf ISA) Les instructions du LC-3 se répartissent en trois classes. Instructions arithmétiques et logiques : ADD, AND, NOT. Instructions de chargement et rangement : LS, ST, LDR, STR, LEA. Instructions de branchement : BR, JSR, TRAP, RET Il y a aussi NOP, pour no operation, qui ne fait rien. . . Pour simplifier les choses, d’autres instructions du jeu d’instruction du LC3 sont ici omises. (cf ISA) Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 20 / 34 Les instructions du LC3 Récapitulatif des instructions du LC-3 Cf feuille jointe + ISA du LC3. La colonne « NZP » indique les instructions qui provoquent la mise à jour des drapeaux NZP. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 21 / 34 Les instructions du LC3 Deux comportements pour ADD (rappel) Notez par exemple que l’addition (ADD) se décline de deux façons : « ADD DR, SR1, SR2 » ajoute les contenus des deux registres sources SR1 et SR2, et place le résultat dans le registre destination DR. « ADD DR, SR1, SR2 » ajoute le contenu de SR1 à un immédiat codé en complément à 2 sur 5 bits, et de place le résultat dans DR. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 22 / 34 Les instructions du LC3 Les instructions de chargement et rangement 1 Introduction à l’architecture du LC-3 2 Les instructions du LC3 Les instructions de chargement et rangement Les instructions de branchement Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 23 / 34 Les instructions du LC3 Les instructions de chargement et rangement LD (principe symétrique pour ST) Soit adI adresse de l’instruction LD considérée. syntaxe : LD DR,label ,→ le label servira à désigner une adresse mémoire AdM. action : DR ← Mem[PC + Sext(PCOffset9)] valeur de PC après son incrémentation lors du chargement : PC = adI+1. l’adresse du chargement est calculé à partir d’un offset codé en complément à 2 sur 9 bits : -2566Sext(PCOffset9)6255. La case mémoire chargée est donc celle à l’adresse : adM = adI + 1 + Sext(PCOffset9), Comme adI − 255 6 adM 6 adI + 256, la distance entre une instruction LD et la case mémoire dont elle peut charger le contenu est limitée, d’où l’utilité de l’instruction LDR. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 24 / 34 Les instructions du LC3 Les instructions de chargement et rangement LD 2/2 adM = adI + 1 + Sext(PCOffset9). I En pratique, c’est l’assembleur qui va se charger du calcul de PCOffset9 le programmeur en langage d’assemblage se contente d’utiliser des labels. label1: 10 data1 label2: 11 data2 12 ... 13 ... 14 ... 15 ... 16 ... 17 LD R1,label1 LD R1,−8 18 ... 19 ... Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 25 / 34 Les instructions du LC3 Les instructions de chargement et rangement LDR (principe symétrique pour STR) syntaxe : LDR DR,baseR,Offset6 action : DR ← Mem[baseR + Sext(PCOffset6)] l’offset est codé en complément à 2 sur 6 bits : −32 6 Sext(Offset6) 6 31. La case mémoire chargée est celle à l’adresse : adM = baseR + Sext(PCOffset6), avec baseR − 32 6 adM 6 baseR + 31. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 26 / 34 Les instructions du LC3 Les instructions de chargement et rangement Utilisation de STR/LDR Avec LDR et STR, on peut accéder à toutes les adresses de la mémoire. On utilise ses instructions pour manipuler des données sur la pile 1 , comme les variables locales des fonctions ; accéder aux éléments d’un tableau. I baseR est utilisé comme un pointeur. Par contre, comment initialiser baseR ? 1. on n’a pas encore vu cette notion Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 27 / 34 Les instructions du LC3 Les instructions de chargement et rangement LEA - chargement d’une adresse dans un registre syntaxe : LEA DR,label action : DR ← PC + Sext(PCOffset9) si adI est l’adresse de l’instruction, l’adresse chargée est : adM = adI + 1 + Sext(PCOffset9), adI − 255 6 adM 6 adI + 256. L’adresse est calculée comme pour un LD, mais seule l’adresse adM est chargée dans DR (pas Mem[AdM]). Cette instruction est utile pour : charger l’adresse d’un tableau dans un registre, charger l’adresse de la base de la pile d’exécution. On s’en sert donc de LEA pour initialiser un pointeur. Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 28 / 34 Les instructions du LC3 Les instructions de branchement 1 Introduction à l’architecture du LC-3 2 Les instructions du LC3 Les instructions de chargement et rangement Les instructions de branchement Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 29 / 34 Les instructions du LC3 Les instructions de branchement BR : registre dédié 1/2 Trois drapeaux N, Z et P (majuscules) du PSR sont mis à jour dès qu’une nouvelle valeur est chargée dans l’un des registres généraux : N passe à 1 si cette valeur est strictement négative, Z passe à 1 si cette valeur est nulle, P passe à 1 si cette valeur est strictement positive. (cf TP circuits combinatoires) Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 30 / 34 Les instructions du LC3 Les instructions de branchement BR : instruction 2/2 L’instruction BR contient elle trois bits n, z et p (minuscules) : syntaxe : BR[n][z][p] label action : si cond alors PC ← PC+Sext(PCOffset9) cond = (n z p) + (n = N ) + (z = Z) + (p = P ) si adI est l’adresse de l’instruction, l’adresse de branchement est : adM = adI + 1 + Sext(PCOffset9), adI − 255 6 adM 6 adI + 256. I On réalise avec BR des branchements inconditionnels ou conditionnels. L’assembleur se charge de calculer PCOffset9 d’après le label fourni : il faut néanmoins garder à l’esprit le fait que la distance du saut est limitée. . . Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 31 / 34 Les instructions du LC3 Les instructions de branchement Un autre exemple de programme 1/3 On veut écrire un programme qui calcule la longueur d’une chaîne de caractères se trouvant à l’adresse désignée par un label string. Le résultat sera stocké à l’adresse désignée par res. On commence par mettre en place la structure de base du programme : .ORIG x3000 ; Partie contenant le code ; Chaine constante string: .STRINGZ "Hello World" res: .BLKW #1 .END Laure Gonnord (L2/FST/Univ Lyon1) ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 32 / 34 Les instructions du LC3 Les instructions de branchement Ex 2/3 : pseudo code à traduire R0 <- &string; // R1 <- 0; // while((R2 <- *R0) R0 <- R0+1; // R1 <- R1+1; // } res <- R1; // Laure Gonnord (L2/FST/Univ Lyon1) R0 pointe vers Le compteur R1 != '\0') { Incrémentation Incrémentation le début de la chaine est initialisé à 0 du pointeur du compteur Rangement du résultat ArchiL2 (LIF6) Cours 06 : Programmation LC3 1/2 2014 33 / 34 Les instructions du LC3 Les instructions de branchement Ex 3/3 : Programme final .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 06 : Programmation LC3 1/2 2014 34 / 34