IUT de Montreuil - Département Informatique 2016-2017 Système 1 TD10 : Initiation à la programmation en assembleur 1 Généralités 1.1 Structure d’un programme en assembleur (vu en cours) .data # zone de données var: #on met les délarations de variables ici .text .globl main # zone d’instructions # étiquette main: #on met les instructions ret # retour .data # ici Exemple : zone de données var1: .byte 65 # un octet initialisé à .byte 1 # un octet à 1 65 en decimal var2: main: .text # zone d’instructions .globl main #étiquette movb var1, %al #copie dans le registre al le contenu #d’un octet à l’adresse associée #à l’étiquette var1 movb %al, var2 ret #retour 1/5 IUT de Montreuil - Département Informatique 1.2 2016-2017 Instructions de copie (vu en cours) movb movw movl movq 1.3 src, src, src, src, des des des des : : : : copier copier copier copier la la la la valeur valeur valeur valeur d’un octet de “src” dans “des” de deux octets de “src” dans “des” de quatre octets de “src” dans “des” de huit octets de “src” dans “des” Instructions de branchement (vu en cours) Les instructions de branchement permettent de modifier directement le contenu du registre IP (compteur de programme) et de changer en conséquence le flux d’exécution de programme. L’instruction de branchement inconditionnel jmp <adresse> permet de sauter à l’instruction se trouvant à une adresse symbolique (étiquette) ou constante. Exemple : .text # zone d’instructions .globl main main: movl jmp movl $2, %eax suite $4, %ebx movl ret %ebx, %eax suite: Les instructions de branchement conditionnel les plus courants : jz <adresse> : sauter à <adresse> si ZF=1 jnz <adresse> : sauter à <adresse> si ZF=0 jc <adresse> : sauter à <adresse> si CF=1 jnc <adresse> : sauter à <adresse> si CF=0 jo <adresse> : sauter si à <adresse> OF=1 jno <adresse> : sauter si à <adresse> OF=0 1.4 Les registres Intel x86 Un processeur de la famille Intel x86 possède un ensemble de registres pour stocker temporairement des données lors d’un calcul. Les registres les plus courants sont : – rax, rbx, rcx, rdx, rsi, rdi, rsp (64 bits) 2/5 IUT de Montreuil - Département Informatique 2016-2017 – eax, ebx, ecx, edx (32 bits) – ax, bx, cx, dx (16 bits) – dh, dl, ch, cl, bh, bl, ah, al (8 bits) Un programme en assembleur peut accéder directement à ces registres. Pour distinguer d’un registre d’une étiquette on le fait précéder par un %. 1.5 Modes d’adressage – L’adressage immédiat (constante) : pour introduire une valeur en une base numérique Exemple : movb $10, %al : copie la valeur 10 dans le registre “al” – L’adressage direct : pour accéder au contenu d’une variable. Exemple : movb var1, %al : copie dans “al” le contenu d’un octet de la variable “var1” – L’adressage registre : pour accéder au contenu d’un registre. Exemple : movb $10, %al – L’adressage indirect : pour récupérer l’adresse d’une case mémoire ou le contenu d’une zone de mémoire pointée par un registre Exemple : – movq $var1, %rsi : copie dans “rsi” l’adresse de la case mémoire associée à la variable “var1” – movw (%rsi), %ax : copie dans “ax” le contenu de deux octets de la zone de mémoire dont l’adresse est indiquée par “rsi” 1.6 Affichage Pour afficher un caractère ou une chaı̂ne de caractères en assembleur, on peut faire appel à l’interruption int 0x80 de Linux. .data # zone de données var: .byte 65 # le code d’ascii de A .string "Bonjour!" # chaine de caractères .text # zone de code .globl main main: movq movq movq movq int ret $4, %rax # pour écrire $1, %rbx # stdout $var, %rcx # l’adresse de la chaine $8, %rdx # le nb de carac. à afficher $0x80 # interruption de Linux pour l’affichage Exercice 1 Parmi les propositions suivantes, lesquelles sont correctes et pourquoi ? 1. %bh, %bl sont des registres d’une capacité de 8 bits 3/5 IUT de Montreuil - Département Informatique 2016-2017 2. Toute modification du contenu de %cl entraine une modification du contenu de %ch 3. Toute modification du contenu de %bl entraine une modification du contenu de %bx, %ebx et %rbx 4. Toute modification du contenu de %rdx entraine une modification du contenu de %edx, %dx, %dh et %dl 5. Une modification du contenu de %rax peut entrainer une modification du contenu de %eax, %ax, %ah, %al Exercice 2 1. Ecrire un programme qui copie respectivement dans %al et %ax le contenu de l’octet de poids fort et des deux octets de poids fort d’une zone de mémoire définie et initialisée par les directives suivantes : .data var4: .byte .byte .byte .byte 1 2 3 4 Donner la valeur de %al et %ax après que les copies sont réalisées. 2. Ecrire un programme qui copie respectivement dans %rax et %rbx le contenu des 8 octets de poids faible et 8 octets de poids fort d’une zone de mémoire de 16 octets associée à une variable définie et initialisée par les directives suivantes : .data var16: .long .long .long .long 1 2 3 4 Donner la valeur de %rax et %rbx après que les copies sont réalisées. 3. Ecrire un programme qui copie respectivement dans %al, %ax, %eax et %rax le contenu d’un octet, de 2 octets, de 4 octets et de 8 octets d’une zone de mémoire définie et initialisée par les directives suivantes : .data var8: .word .word .word .word 1 2 3 4 Donner la valeur de %al, %ax, %eax et %rax après que les copies sont réalisées. 4/5 IUT de Montreuil - Département Informatique 2016-2017 Exercice 3 1. Ecrire un programme qui réalise une addition et affiche un message s’il y a un débordement. Tester votre programme avec des nombres non signés et signés. 2. Ecrire un programme qui copie 100 octets d’une zone de mémoire dans une autre. 5/5