L`interface Matériel Logiciel II. Le Langage d`assemblage
Transcription
L`interface Matériel Logiciel II. Le Langage d`assemblage
Introduction aux systèmes Informatiques: L’interface Matériel Logiciel (A3- 2016/2017) Léon Mugwaneza Polytech’ Marseille/Dépt. Informatique (bureau A118) [email protected] II. Le Langage d’assemblage Ecrire des prog. en langage machine ? s w a p ( in t v [ ] , in t k ) { in t te m p ; te m p = v [ k ]; v [ k ] = v [k + 1 ]; v [k + 1 ] = te m p ; } programme en langage C Traducteur 0 0 1 1 1 1 0 000 000 000 000 010 010 000 00 00 11 11 11 11 00 001010 00 001000 11 000110 00 001111 00 001111 00 00011000 11111000 01 10 10 10 10 10 00 000 000 000 000 000 000 000 0000000011 1100000100 0000000000 0000000000 0000000000 00 00000000 00 00000001 00 00 00 10 00 10 00 0 1 0 0 0 0 0 programme en langage Machine 2 Lang. machine / Lang. d’assemblage/C s w a p ( in t v [ ] , in t k ) { in t te m p ; te m p = v [ k ]; v [ k ] = v [k + 1 ]; v [k + 1 ] = te m p ; } programme en langage C Compilateur sw a p : m u li $ 2 , $ 5 , 4 a d d $ 2 , $ 4 ,$ 2 lw $ 1 5 , 0 ($ 2 ) lw $ 1 6 , 4 ($ 2 ) sw $ 1 6 , 0 ($ 2 ) sw $ 1 5 , 4 ($ 2 ) jr $ 3 1 programme en langage d’assemblage Assembleur 0 0 1 1 1 1 0 000 000 000 000 010 010 000 00 00 11 11 11 11 00 001010 00 001000 11 000110 00 001111 00 001111 00 00011000 11111000 01 10 10 10 10 10 00 000 000 000 000 000 000 000 0000000011 1100000100 0000000000 0000000000 0000000000 00 00000000 00 00000001 Ce schéma n’est pas complet 00 00 00 10 00 10 00 0 1 0 0 0 0 0 programme en langage machine 3 Le langage d’assemblage • C’est le premier langage de «haut niveau» – plus compréhensible (pour l’humain) que le langage machine – la machine ne comprend que le langage machine (les 0 et les 1) depuis le début nous avons utilisé une bonne partie du langage d’assemblage (notations pour les codes opération et les opérandes): nous sommes (quasi) incapables de «parler» le langage machine • Souvent appelé «Assembleur» – à tort ! – l’assembleur (assembler) est l’outil de traduction langage d’assemblage (assembly language) vers le langage machine (machine language) 4 Langage d’assemblage : principes généraux • Un programme en langage d’assemblage comprend – des instructions «exécutables» qui seront traduites en instructions du niveau langage machine – des directives destinées à l’outil de traduction (l’assembleur) • les directives servent à décrire l’organisation du programme, la réservation de la mémoire pour des données, la définition de «macros», etc. 5 Langage d’assemblage : les instructions • Le langage d’assemblage fournit une représentation symbolique (mnémoniques car mnémo-techniques) des instructions (opérations et opérandes) • On distingue : – instructions (codes opération et modes d’adressage) du langage machine – pseudo-instructions : instructions nouvelles et modes d’adressage nouveaux » les pseudo-instructions sont traduites en de courtes séquences d’instructions de l’ISA » exemples de pseudos : • blt $a0, $a1, 50 • nop » addi $t0, $t1, 0x6F1AB Comment sait-on qu’une instruction est une pseudo ? 6 Langage d’assemblage : les directives • Les directives assembleur sont destinées au programme de traduction (l’assembleur) et concernent : – l’organisation du programme » un programme est découpé en des zones (ou sections) «texte» (ou code) contenant les instructions et des zones «données» contenant les «données globales» – la réservation de place pour les données. On distingue : » données initialisées » données non initialisées – la définition de constantes nommées (pour une meilleure lisibilité des programmes) – la définition de macros – l’organisation de la mémoire (cf. contraintes d’alignement) – … (ex. commentaires du compilateur) 7 Langage d’assemblage : syntaxe (1/2) • Qui définit le langage machine? • Qui définit le langage d’assemblage? – Le langage machine (ISA) est obligatoirement défini par le constructeur – Pour le même ISA, on peut définir plusieurs langages d’assemblage » MAIS, dans la plupart des cas (pour ne pas dire tous les cas) le constructeur fournit au minimum les mnémoniques pour les instructions – Les langages d’assemblage correspondant au même ISA vont différer au niveau de la notation pour les modes d’adressage, l’ordre des opérandes, les directives, et les pseudo-instructions 8 Langage d’assemblage : syntaxe (2/2) • Un programme en langage d’assemblage est une suite de lignes • Chaque ligne est décomposée en 3 champs Etiquette (optionnelle) Instruction ou directive (optionnelle) Commentaire (optionnel) – chacun des champs est optionnel – les commentaires peuvent être précédés d’un «délimiteur» – en général, un commentaire en début de ligne est précédé d’un délimiteur (; , #, …) • La syntaxe des premiers langages d’assemblage était très contraignante (taille des étiquettes limitée, seules les étiquettes commencent en début de ligne, …) 9 Langage d’assemblage du simulateur SPIM • SPIM (MIPS à l’envers) est un simulateur de MIPS R2000 développé par James Larus (univ. Wisconsin-Madison, actuellement à Microsoft Research) • Pourquoi utiliser un simulateur ? – ça coûte moins cher (gratuit, versions Linux, Unix, Windows et dos !) – c’est très facile à maintenir – chacun dispose de sa propre machine (voire de plusieurs !) • Limitations du simulateur par rapport à un vrai ordinateur à base de MIPS? – pas de pannes hardware (est ce vraiment une limitation ?) – les durées des instructions (notamment pour les opérations sur les flottants), les temps d’accès à la mémoire ne correspondent pas à ceux du processeur réel – ... 10 SPIM : les instructions • Les mnémoniques – déjà vus (cf. «Le Langage Machine : Exemple – le MIPS R2000») • Les modes d’adressage – déjà vus (cf le MIPS R2000). Le MIPS dispose de 5 modes d’adressage » direct registre (ex. $1, $at, $26, $k1) » immédiat (ex. 50, 0x0032, -50, 0xFFCE) (la valeur est sur 16 bits) » relatif PC (ex. +50 instructions) » basé (ex. 100($t0), 0xFFCE($t0)) (le déplacement est sur 16 bits) » pseudo direct mémoire (ex. 0x004000 dans j 0x004000) 11 SPIM : les pseudo instructions • Les nouveaux modes d’adressage – En plus des notations pour les 5 modes d’adressage du langage machine, le langage d’assemblage SPIM définit 6 nouveaux modes d’adressage : » immédiat avec valeur sur 32 bits (ex. 0x 12345) » basé avec déplacement sur 32 bits (ex. 0x12345($t0) » étiquette : interprétée comme adresse, déplacement ou valeur immédiate sur 32 bits en fonction de l’instruction • (ex. jal fact ou beq $0, $0, fact ou la $a0, fact) » étiquette(registre) : @étiquette + registre » étiquette +/- valeur : @étiquette +/- valeur » étiquette +/- valeur(registre) : @étiquette +/-(valeur+registre) – une instruction utilisant un de ces nouveaux modes d’adressage est traduite en une ou plusieurs instructions du langage machine 12 Pseudo modes d’@ge spim : exemple (1/6) • Soit la séquence d’instruction en langage d’assemblage SPIM suivante : loop: lw bne add addi j exit: $8, debutT($9) $8, $21, exit $19, $19, $8 $9, $9, 4 loop (1) (2) (3) • Supposons que : – debutT soit une étiquette correspondant à l’adresse 0x10000004 – loop correspond à l’adresse 0x00400020 13 Pseudo modes d’@ge spim : exemple (2/6) • (1) est traduit en : lui ori addu lw $at, 0x1000 $at, $at, 0x0004 $at, $at, $9 $8, 0($at) • Aurait-on pu faire plus « efficace » (plus court) ? – Le déplacement dans l’instruction lw est 0 ! ==> on peut optimiser lui $at, 0x1000 addu $at, $at, $9 lw $8, 0x0004($at) – Et si debutT correspondait à l’adresse 0x10008004 ? 14 Pseudo modes d’@ge spim : exemple(3/6) – Et si debutT correspondait à l’adresse 0x10008004 ? • Solution 1 lui ori addu lw $at, 0x1000 $at, $at, 0x8004 $at, $at, $9 $8, 0($at) • Solution 2 lui $at, 0x1000 addu $at, $at, $9 lw $8, 0x8004($at) # $at = 0x1000 0000 # $at = 0x1000 0000 + $9 # $8 = M[$at+0xFFFF 8004] – la solution 2 est incorrecte car l’adressage basé a un déplacement signé (extension de signe du déplacement avant le calcul de l’adresse : 0x8004 devient 0xFFFF8004) – un assembleur qui fait une traduction systématique utilisera donc la première solution 15 Pseudo modes d’@ge spim : exemple (4/6) • Après la traduction de la pseudo (1) on a : loop: lui ori addu lw bne add addi j exit: $at, 0x1000 $at, $at, 0x0004 $at, $at, $9 $8, 0($at) $8, $21, exit (2) $19, $19, $8 $9, $9, 4 loop (3) • Pour traduire (2), il faut connaître le nombre d’instructions du langage machine entre l’instruction bne et la déclaration de l’étiquette exit – Il faut donc traduire (3) d’abord (les 2 autres instructions sont des instructions du langage machine) 16 Pseudo modes d’@ge spim : exemple (5/6) • En supposant que loop correspond à l’adresse 0x00400020, (3) est traduit en : j 0x00400020 # code de l’instruction : 0x08100008 (seuls 26 bits de cette adresse sont utilisés) • j loop se traduit en une instruction et donc se traduit par : (avec l’hypothèse que PC contient l’adresse de l’instruction en cours) bne $8, $21, exit bne $8, $21, 16 nombre d’octets en langage machine le 16 deviendra 4 On aurait pu choisir de mettre 4 en langage d’assemblage, mais de toutes les façons le programmeur utilisera les étiquettes 17 Pseudo modes d’@ge spim : exemple (6/6) • Implantation en mémoire du programme final (en supposant debutT = 0x10000004 et loop = 0x00400020) 0x00400020 loop: lui 0x00400024 ori 0x00400028 addu 0x0040002C lw 0x00400030 bne 0x00400034 add 0x00400038 addi 0x0040003C j 0x00400040 exit: $at, 0x1000 $at, $at, 0x0004 $at, $at, $9 $8, 0($at) $8, $21, 16 $19, $19, $8 $9, $9, 4 0x00400020 lw $8, debutT($9) bne $8, $21, exit j loop G Et en langage machine ? Exercice 18 SPIM : les pseudo-instructions • Les nouveaux mnémoniques – une pseudo-instruction est une instruction du langage d’assemblage à laquelle ne correspond pas une instruction du langage machine – SPIM et les autres langages d’assemblage du MIPS définissent quelques nouvelles «instructions» pour faciliter l’écriture des programmes – ces nouvelles instructions (pseudo-instructions) sont traduites en plusieurs instructions du langage machine (séquence de vraies instructions MIPS) quelques exemples (se référer à la doc «Assembers, Linkers, and the SPIM Simulator» pour la liste complète des pseudo-instructions définies par SPIM) 19 Pseudo-instructions - exemples (1/3) • move : Transfert entre registres généraux move reg2,reg1 est traduite en add reg2,$zero,reg1 • li : Load Immediate (chargement d’une constante dans un registre) li reg,value – si value tient sur 16 bits : addi reg,$zero,valeur – si value ne tient pas sur 16 bits : lui reg, 16 bits de poids forts de valeur ori reg, reg, 16 bits de poids faibles de valeur • la : load address (chargement d’une adresse dans un registre) la reg,adresse est traduit en : $at ← <adresse effective> add reg, $zero, $at ( adresse correspond à une adresse mémoire exprimée à l’aide d’un des modes adressage ( [étiquette][+/-valeur][(reg)]) 20 Pseudo-instructions : exemples (2/3) • ror : ROtate Right ror reg, valeur est traduit par : srl sll or $at, reg, valeur reg, reg, 32-valeur reg, reg, $at 0! 0! • nop : No Operation nop est traduit en l’instruction de code 0 sll $0, $0, 0 21 Pseudo-instructions : exemples (3/3) • Mnémoniques “incorrects” pour les opérandes addu reg,reg,valeur # on devrait utiliser addiu si valeur tient sur 16 bits : addiu reg,reg,valeur sinon : lui $at, 16 bits de poids forts de valeur ori $at,$at, 16 bits de poids faibles de valeur addu reg,reg,$at 22 Pseudo-instructions : exercice (1/2) • Lesquelles des instructions en langage d’assemblage suivantes sont des pseudoinstructions? (ne sont pas de vraies instructions du MIPS ?) i. ii. iii. addi $t0, $t1, 40000 beq $s0, 10, -20 sub $t0, $t1, 1 23 Pseudo-instructions : exercice (2/2) • Lesquelles des instructions langage d’assemblage suivantes sont des pseudoinstructions? (ne sont pas de vraies instructions du MIPS ?) i. ii. iii. addi $t0, $t1, 40000 40 000 > +32 767 =>lui,ori beq $s0, 10, -20 beq: les 2 premières opérandes sont des regs! sub $t0, $t1, 1 sub: les 2 sources doivent être des regs; même si l’instruction était subi, il n’y a pas de subi en Langage Machine. (est traduit en addi $t0,$t1, -1)! 24 Autre exercice • Lesquelles des instructions en langage d’assemblage suivantes sont des pseudo-instructions? i. ii. iii. iv. v. vi. vii. viii. ix. mult $t0, $t1, $t2 beq $s0, $s1, Exit j Exit addi $t0, $t1, 20000 addiu $t0,$t1, 40000 li $t0, 0x20000 li $t0, 20000 la $t0, debutT lw $t0, 40000($zero) A faire pour voir si vous avez compris (vous pouvez vous servir du simulateur xspim – voir diapos suivantes) 25 SPIM : la syntaxe • Quelques mots (se référer à la doc) – commentaires : du délimiteur # jusqu’à la fin de la ligne – étiquettes : identificateur terminé par le caractère ‘ : ’ (deux points). Elles sont en début de ligne (cf format d’une instruction LA). Il ne peut y avoir deux déclarations d’étiquette sur la même ligne – identificateurs : séquences de «caractères alpha-numériques», «souligné», et «point» ne commençant pas par un chiffre » les mnémoniques des instructions sont réservés (ne peuvent pas être utilisés comme identificateurs) – les nombres sont en base 10 par défaut, les nombres en notation héxadécimale sont précédés par 0x (ex: 0x12 = 18) – les constantes chaînes de caractères sont entre guillemets –double quote(ex: ”une chaîne”) – les caractères spéciaux sont notés de la même façon qu’en langage C » \n (new line) » \t (tab) » \ ” (guillemet – double quote-) – ... 26 SPIM : les directives (1/4) • Organisation du programme – Déclaration de zones de données Données utilisateur .data [<adr>] par défaut <adr> = 0x10000000 Données système .kdata [<kadr>] par défaut <kadr> = 0x90000000 – Déclaration de zones de code (texte) Code utilisateur .text [<adr>] par défaut <adr> = 0x00400000 Code système .ktext [<kadr>] par défaut <kadr> = 0x80000000 On peut placer des données initialisées dans une zone de code ☞ mélange instructions et données: non recommandé, mais il y a quelques cas où c’est justifié – ex traduction switch (voir ch. 3 ) 27 SPIM: les directives (2/4) • Réservation de place mémoire pour les données label: .space n # n entier positif réserve n octets. L’adresse est repérée par l’étiquette label (label est optionnel) – Données initialisées .byte b1,b2, … , bn initialise n octets avec les valeurs b1, b2, …, bn .word w1, w2, …., wn initialise n mots (4n octets) avec les valeurs w1, w2, … , wn (alignement à une frontière de mots pour w1) .half, .float, .double (idem .byte et .word) ! .ascii <str> initialise une zone mémoire avec la chaîne de caractères <str> .asciiz <str> initialise une zone mémoire avec la chaîne de caractères <str> suivie d’un octet à 0 (caractère \0) .align 0 ==> pas d’alignement automatique par .word, .half, ... – Données non initialisées 28 SPIM: les directives (3/4) • Utilisation du registre $1 .set noat! Le programme peut utiliser $1 ($at) .set at $1 ($at) est reservé à l’assembleur et son utilisation est une erreur • Quand a-t-on besoin d’utiliser (de manipuler) $1 ? – l’assembleur utilise $1 pour traduire les pseudo-instructions – étant donné le nombre de registres dont on dispose, réserver $1 à l’assembleur n’est pas vraiment une restriction – le système a besoin de manipuler $1 lors des sauvegardes et restaurations de l’état d’un programme en cours d’exécution suite à une exception. On a une séquence du type : .set noat! <sauvegarde ou restauration de $at>! .set at! 29 SPIM : les directives (4/4) .globl <sym>! Le symbole <sym> est global, et peut être référencé à partir d’autres modules (cf. Assemblage et édition de liens) • Alignement .align n ! Aligne la donnée suivante sur une frontière de 2n octets ( .align 2 ==> frontière de mots) Machine big endian @Ex 00 05 00 00 .word 0x00050000 @Ex+ 4 .space 5 .align 2 Toto: .byte 0xA, 0xFB, 0x3C, 0xD @Toto xx xx xx xx 0A FB 3C 0D Ex : xx .align 0 ==> pas d’alignement automatique par .word, .half, .float • Déclaration de symboles globaux 30 SPIM : exemple (1/2) • Soit à traduire l’algorithme suivant : Algorithme sigma50 /* somme des 50 premiers entiers positifs non nuls */ Variables SOMME, COMPTEUR : entiers Debut SOMME ← 0 COMPTEUR ← 50 boucle: si COMPTEUR < 1 alors aller à Suite sinon SOMME ← SOMME + COMPTEUR COMPTEUR ← COMPTEUR - 1 aller à boucle Suite : afficher(SOMME) fin On supposera que : – COMPTEUR est dans le registre $s0 – SOMME est en mémoire (dans une zone de données) 31 SPIM : exemple (2/2) !.data .align 2 SOMME: .space 4 # main: # .word 0 .text .globl main SOMME ← 0 sw $0, SOMME($0) COMPTEUR ← 50 li $s0, 50 #boucle: si COMPTEUR < 1 alors aller à Suite li $t1, 1 boucle:blt $s0,$t1, suite # # # # sinon SOMME ← SOMME + COMPTEUR lw $t2, SOMME($0) add $t2, $t2, $s0 sw $t2, SOMME($0) COMPTEUR ← COMPTEUR - 1 addi $s0, $s0, -1 aller à boucle beq $0, $0, boucle # suite : afficher(SOMME) suite: lw $t2, SOMME($0) # instructions pour afficher l’entier dans $t2 #fin jr $ra 32 SPIM: utilisation de la mémoire • Mémoire utilisateur 0x7FFFFFF Pile (voir plus loin) Données dynamiques (voir plus loin) Données statiques ( de .data) 0x10000000 0x00400000 Zone de code (de .text) réservé • Mémoire système : < à 0x00400000 et > à 0x80000000 33 • 2 interfaces Le simulateur SPIM – interface texte (spim) – interface graphique (xspim) • 2 modes de fonctionnement – bare : les pseudo instructions ne sont pas autorisées – asm normal : les pseudo sont autorisées (par défaut) • Lancement et terminaison d’un programme – xspim initialise les registres (mis à 0 sauf pour $sp et $gp), – une « amorce » est ensuite chargée à l’@ de début du segment (de la zone) « texte » (0x0040 0000) et appelle la procédure main (instruction jal main) – au retour de la procédure main, l’amorce fait un appel au service système «exit» pour terminer le programme – d’autres services systèmes sont disponibles (cf figure A17 page A-49) • xspim instalé sur ens1 et ens2 – La doc distribuée (et disponible sur page web du cours) correspond à la version 6.5 – ISA MIPS-I (utilisée dans ce cours, installée sur le compte de l’enseignant : ~mugwaneza/xspim) 34 (cf. XSPIM «Assemblers, linkers, & the SPIM simulator» page A-41) 35 Fin du chapitre II 36