Lycée lissan eddine ibn_elkhatib laayoune Filière BTS DSI ASSEMBLEUR Module N°3 BTS DSI 1 Pr H.LAARAJ [email protected] http://lewebpedagogique.com/laarajbts 2015/2016 L’OBJECTIF DE CE COURS L’objectif de ce cours est de savoir: Le fonctionnement interne d’un ordinateur. Comment le processeur exécute les instructions stockées dans la RAM. Quelles sont les opérations élémentaires que le microprocesseur pourra exécuter. Programmer avec des langages de bas niveau proche de langage binaire compris par le matériel. Comment le processeur exécute les conditions « if » et les boucles « for,while,… » de langage de haut niveau (C,VB,…) 2 Partie I Introduction à l’assembleur Instruction mov Instructions des opérations (add,div,and,or,…) Instructions de branchement (jmp,jnz,…) Instruction de comparaison (cmp) Appel des fonctions (invoke,call) 3 I-INTRODUCTION À L’ASSEMBLEUR: BTS DSI 4 I.1 DÉFINITION DE L’ASSEMBLEUR: est le langage de programmation de plus bas niveau. Cela signifie qu’il est trop proche du matériel, qui oblige le programmeur à se soucier de concepts proches du fonctionnement de la machine, comme la mémoire, processeur. transforme un fichier source contenant des instructions, en un fichier exécutable que le processeur peut comprendre. Les programmes faits en ASM sont plus petits, plus rapides et beaucoup plus efficaces que ceux fait avec des compilateurs(C,java,vb,…) 5 Langage humain Langage de programmation : Haut niveau (Par exemple, le C) Compilation Langage Assembleur Assemblage Langage Machine : (code binaire) 6 7 I.2 LE CHOIX DE LANGAGE ASSEMBLEUR Vu que l’assembleur est qualifié comme étant le langage de programmation le plus bas niveau, il dépend donc fortement du type de processeur. Ainsi il n'existe pas un langage assembleur, mais un langage assembleur par type de processeur. Dans notre cours on va utiliser assembleur MASM32 (Macro Assembleur de Microsoft) pour la famille de processeurs x86 32bits. MASM32 maintenu par Steve Hutchesson permet de programmer directement et relativement aisément des applications 32 bits fonctionnant sous Windows 8 II- LE PROCESSEUR(CPU) ET LA MÉMOIRE(RAM) BTS DSI 9 II.1 FONCTIONNEMENT D’UN PROGRAMME Processeur RAM 00401000 A155 EAX 0000567A 00401002 BD46B5 EBX 56D3507E 00401005 6A00 code … EIP 00401000 A155 00403000 0000567A 00403004 56D3507E data 10 II.2 LES REGISTRES Il existe plusieurs types de registres et chacun a son utilité. registres généraux (EAX, EBX, ECX, EDX) Ils servent à manipuler des données, à transférer des paramètres lors de l’appel de fonction DOS et à stocker des résultats intermédiaires. registres d’offset ou pointeur (EIP, ESI, EDI, ESP, EBP) Ils contiennent une valeur représentant un offset à combiner avec une adresse de segment registres de segment(CS, DS, SS, ES, FS, GS) Ils sont utilisés pour stocker l’adresse de début d’un segment. Il peut s’agir de l’adresse du début des instructions du programme, du début des données ou du début de la pile. Un registre de flag Il contient des bits qui ont chacun un rôle indicateur. 11 II.3 LES REGISTRES GÉNÉRAUX EAX -- accumulateur -- sert à effectuer des calculs arithmétiques ou à envoyer un paramètre à une interruption EBX -- registre auxiliaire de base -- sert à effectuer des calculs arithmétiques ou bien des calculs sur les adresses ECX -- registre auxiliaire (compteur) -- sert généralement comme compteur dans des boucles EDX -- registre auxiliaire de données -- sert à stocker des données destinées à des fonctions Ceci est leur utilisation théorique, mais dans la pratique ils peuvent être utilisés à d'autres usages. 12 II.3 REGISTRE EAX EAX(32 bits) AX(16 bits) AH(8bits) AL(8bits) 13 II.4 JEU D’INSTRUCTIONS D’UN CPU Décrit l’ensemble des opérations élémentaires que le microprocesseur pourra exécuter. Transfert de données: charger ou sauver en mémoire (mov , …) Opérations arithmétiques (add ,mul ,div , …) Opérations logiques( and ,or , …) Contrôle de séquence : - Branchement (jmp, jnz…) « c’est le saute » - Test (cmp,…) « c’est la comparaison » 14 III- LANGAGE MASM32 BTS DSI 15 III.1 DÉCLARATION DE VARIABLES Les variables se déclarent de la manière suivante: en 8bits : nom_Variable DB valeur en 16bits : nom_Variable DW valeur en 32bits : nom_Variable DD valeur De manière générale: DB (Declare Byte) : 1 byte (8 bits) DW (Declare Word) : 1 word (16 bits) DD (Declare Double) : 2 words (32 bits) Les valeurs peuvent être écrites en: - décimal: 1, 2, 3, 123, 45 - hexadécimal : 1h,2h,3h,12h,0Fh,0AD4h (noter la présence du 0 quand le premier chiffre du nombre en hexadécimal commence par une lettre) - binaire : 1b,0b,1010b,111101b Exemple: var1 db 6 ; var1 est un byte initialisé à 6 en décimal var2 db 0FFh ; var2 est un byte initialisé à FF en hexadécimal var3 dw 67h ; var3 est un word initialisé à 67 (16 bits) 16 var4 dd 67A3h ; var3 est un double word initialisé à 67A3 (32 bits) III.2 STRUCTURE DE CODE MASM32 ; entête de code *************************** .386 ; processeur = Pentium .model flat, stdcall ; un seul segment de 4Go ; déclaration des variables***************** .data var1 dd … … ; code masm32*************************** .code start: … ; les instructions de base masm32 end start 17 III.3 INSTRUCTION MOV mov destination, source L'instruction la plus utilisée est l'instruction mov, qui copie la valeur d'un opérande source dans un opérande destination. La syntaxe est la suivante : mov reg, reg (registre à registre) mov reg, mem (mémoire à registre) mov mem, reg (registre à mémoire) mov reg, imed (registre à valeur) mov mem, imed (mémoire à valeur) NOTE: Pas de transfert de mémoire à mémoire 18 III.4 INSTRUCTIONS DE BASE ARITHMÉTIQUE Incrémentation INC EAX ; EAX <- EAX + 1 INC ma_variable Décrémentation DEC EAX DEC ma_variable Addition ADD EAX, 5 ; EAX <- EAX + 5 ADD BH, var ; BH <- BH + bar ADD var, ECX ; var <- var + ECX Soustraction SUB EAX, 5 ; EAX <- EAX – 5 SUB BH,var ; BH <- BH – var SUB var, CX ; var <- var – CX Multiplication MUL EBX ; EAX <- EBX * EAX Division DIV EBX ; EAX <- EAX / EBX ;Il faut que EDX=0 19 EXEMPLE1: Programme masm32 qui calcule somme de 6A+B5 et stock le résultat dans EAX .386 .model flat, stdcall .data ; variables globales initialisées x dd 6Ah y dd 0B5h .code start: mov EAX, x add EAX, y end start 20 III.5 INSTRUCTIONS DE BASE LOGIQUE AND bit à bit MOV AL, 0101b ; AL <- 5 MOV BL, 1001b ; BL <- 9 AND AL, BL ; AL <- AL AND BL; AL vaut 0001b, soit 1 OR bit à bit MOV AH, 0101b ; AH <- 5 MOV BH, 1001b ; BH <- 9 Or AH, BH ; AH <- AH OR BH; AH vaut 1101b , soit 13 21 III.6 APPEL D'UNE FONCTION invoke fonction a, b, c ; appelle fonction(a, b, c) ;Le résultat d'une fonction est toujours dans eax Remarque: pour appeller une fonction qui utilise des bibliothèques, il faut les importer par le mot clé include ou bien includelib include pour inclure les biblios .inc includelib pour inclure les biblios .lib 22 III.6.2- fonction prédéfini d’affichage à l’écran Syntaxe : invoke StdOut , ADDR msg Avec msg : le texte à afficher à l’écran Remarque: pour utiliser la fonction StdOut , il faut importer les bibliotheques : include \masm32\include\kernel32.inc include \masm32\include\masm32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib 23 EXEMPLE2: Code masm32 qui afficher un message à l’écran .386 ; processeur = Pentium .model flat, stdcall ; un seul segment, appel standard ;--------------------------------------------------------------------------------include \masm32\include\kernel32.inc include \masm32\include\masm32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib ;---------------------------------------------------------------------------------.data msg db "Bonjour : ",0 .code start: invoke StdOut , ADDR msg ici: jmp ici end start 24 III.6.3 fonction de la conversion de hexadécimal to ascii Syntaxe : invoke dwtoa , eax, ADDR z La valeur hexadécimal de eax sera converti en ascii Exemple: eax = F -> z =15 25 EXEMPLE3 : Code masm32 qui calcule et affiche la somme de 2 nombres .data ; variables globales initialisées x dd 10 y dd 11 .data? z dd ? ; variable globale non initialisée .code start: mov eax, x add eax, y invoke dwtoa , eax, ADDR z invoke StdOut ,ADDR z ici: jmp ici end start 26 III.7- LE BRANCHEMENT : III.7.1 Introduction En informatique, un branchement est une opération consistant à se déplacer au sein d'un code exécuté par un processeur, en « sautant » à une adresse identifiée au lieu de poursuivre l'exécution du code séquentiellement. il n'existe que deux types de branchements : les branchements inconditionnels, qui permettent d'aller à une adresse de manière systématique. les branchements conditionnels, qui sont dépendant d'une information particulière. Dans la grande majorité des cas, ces informations sont récupérées dans le registre flag du microprocesseur. 27 III.7.2 Instructions de branchement inconditionnel JMP étiquette_de_destination L'instruction JMP permet d'effectuer un saut inconditionnel, c'est-àdire que cette instruction va stocker dans le registre IP l'adresse de l'instruction que l'on veut exécuter. L'opérande de cette instruction (étiquette_de_destination) est donc l'adresse de l'instruction à laquelle on veut sauter. Une fois l'instruction de branchement exécutée le processeur lit le contenu du registre IP et saute donc directement à l'adresse de l'instruction que l'on vient de définir JMP FIN … … FIN: (ne pas oublier les : ) … … 28 Rq: jmp change la valeur du compteur ordinal (IP : Instruction Pointer). III.7.3 Le registre Flag Les bits de cet ensemble sont appelés "indicateurs". Les instructions arithmétiques, logiques et de comparaison modifient la valeur des indicateurs. Les instructions conditionnelles testent la valeur des indicateurs et agissent en fonction du résultat. Les bits les plus importants: -ZF : Zero Flag - Indicateur zéro Si le résultat d'une opération est nul (égal à 0) ZF passera à 1. -SF : Sign Flag - Indicateur de signe SF passe à 1 quand le résultat est négatif. -CF : Carry Flag - Indicateur de retenue CF=1 s'il y a une retenue de générée, sinon CF = 0, 29 EXEMPLE Sur un processeur de 8bits , donner le résultat des opérations suivantes et positionner les indicateurs 25h+5Ah=? ZF= … SF= … CF= … B5h+4Ah=? ZF= … SF= … CF= … FEh+02h=? ZF= … SF= … CF= … 70h+E0h=? ZF= … SF= … CF= … 30 III.7.4 Instructions de comparaison CMP destination, source Compare la source et la destination; soustrait la source à la destination et met 1 dans le « flag » (drapeau) zero (ZF) si le résultat est nul et 1 dans le « flag » sign (SF) si le résultat est négatif. CMP EAX, EBX ; met 'ZF' a 1 si EAX=EBX ; met 'SF' a 1 si EAX < EBX 31 III.7.5 Instructions de branchement conditionnel Suit une instruction de comparaison (CMP) et réalise le saut en fonction des drapeaux, c'est-à-dire du résultat de la comparaison. Sinon passe à l'instruction suivante. JZ DEBUS JNZ PLACE JS RET JNS START ; saute à DEBUS si le flag ZF est à 1 ; saute à place si le flag ZF est à 0 ; saute à RET si le flag SF est à 1 ; saute à START si le flag SF est à 0 En jouant sur l'ordre des registres on peut réaliser toutes les comparaisons (>, <, >=, <=, =, ! =). 32 III.7.6 La condition : if MOV AL, op1 MOV BL, op2 ; ou autres registres CMP AL, BL ou BL, AL J?? vrai ; instructions du cas_faux JMP fin vrai: ; instruction du cas_vrai fin: où J?? est un des branchements possibles (JZ, fonction de la condition : condition traduction op1 = op2 CMP AL, BL puis JZ ... op1 != op2 CMP AL, BL puis JNZ ... op1 < op2 CMP AL, BL puis JS ... op1 > op2 CMP BL, AL puis JS ... op1 >= op2 CMP AL, BL puis JNS ... op1 <= op2 CMP BL, AL puis JNS ... JNZ, JS ou JNS) en explication op1-op2 = 0 op1-op2 != 0 op1-op2 < 0 op2-op1 < 0 op1-op2 >= 0 op2-op1 >= 0 33 EXEMPLE4: Code masm32 qui vérifier si un nombre est null .data x dd 60 msg1 db "nombre est null ",0 msg2 db "nombre est non null ",0 .code start: mov eax,x cmp eax,0 jz alors invoke StdOut , ADDR msg2 jmp fin: alors: invoke StdOut , ADDR msg1 fin: ici: jmp ici end start 34 III.7.7 Les boucles (avec compteur ) pour i de 1 à limite faire bloc_à_répéter Fin pour La boucle pour se traduit comme suit : MOV registre1, 1 ; compteur i MOV registre2, N pour: CMP registre1, registre2 JNS fin ; registre 1 > registre2 ;bloc_à_répéter … INC registre1 ; incrémentation de i JMP pour fin: 35 EXEMPLE5: Code masm32 qui affiche BTS 6 fois .data msg db "BTS ",0 .code start: mov ebx, 0 rpt: cmp ebx,6 jns fin ; deplacer vers fin si ebx > = 6 invoke StdOut , ADDR msg inc ebx jmp rpt fin: ici: jmp ici end start 36 III.8 INSTRUCTION LEA lea calcule l'adresse effective de l'opérande source et place le résultat dans l'opérande destination. lea reg, mem C'est la façon de mettre dans un registre l'adresse d'une variable. Exemple: l'instruction : lea eax, var1 place dans eax l'adresse mémoire de la variable var1. Remarque : Ceci n’a généralement d’intérêt que si var1 est une variable de type tableau. 37