ASM

Un peu d'assembleur – carnet de bord

14-12-2014


Le programme le plus simple du monde

Le but de cet article est très simple : mettre les pieds dans le plat, et les mains dans le cambouis. À la toute fin, vous devriez être capable de bredouiller quelques mots d'assembleur, de compiler votre code et de l’exécuter. N'avez-vous pas hâte !?

Faisons un sort aux trois questions

Bon, par où commencer ? Comme je l'ai écrit dans l'article d'introduction, il y a trois choix à faire avant de se lancer dans l'assembleur.

Pour éviter toute tergiversation, prenons GNU/Linux, 32 bits et la syntaxe AT&T. Et hop, plus de questions à se poser ! Si comme moi vous travaillez sur un système 64 bits, pas d'panique. Votre distribution devrait déjà avoir tout ce qu'il lui faut pour jouer avec du code 32 bits. Vous aurez juste deux paramètres supplémentaires à ajouter lors de la compilation, rien de mortel.

Premier bout de code

Pour commencer, écrivons le programme le plus simple du monde : un programme qui ne fait rien. Oui, je comprends que vous soyez impatient.

Dans un fichier auquel vous donnerez un nom qui vous plaît mais se terminant par l'extension .s, écrivez le code suivant.


#PURPOSE:   Simple program that exits and returns a
#           status code back to the Linux kernel

#OUTPUR:    returns a status code. This can be viewed
#           by typing:
#            echo $?
#           after running the program
#

#VARIABLES: %eax holds the system call number
#           %ebx holds the return status
#
.section .data

.section .text
.globl _start
_start:
    movl $1, %eax       # This is the linux kernel command
                        # number (system call) for exiting
                        # a program

    movl $1, %ebx       # This is the status number we will
                        # return to the operating system.

    int $0x80           # This wakes up the kernel to run
                        # the exit command

D'après Programming from the Ground Up.

Compilation

Pour compiler un programme assembleur, la démarche en deux étapes sera toujours la même.

Sur un système 32 bits.

as exit.s -o exit.o
ld exit.o -o exit

Sur un système 64 bits.

as exit.s -o exit.o --32
ld exit.o -o exit -m elf_i386

Remarquez que ici, exit.s est le nom du fichier dans lequel j'ai écrit mon programme.

Pour exécuter votre programme, utilisez simplement :

./exit

À vous de jouer !

Décortiquons

Bon alors, est-ce que ça a marché ? Qu'est ce qu'il s'est passé lorsque vous avez lancé votre programme ? Rien ? C'est normal ! Je vous avais prévenu, non ?

Commentaires

En assembleur, les commentaires s'ajoutent après un dièse : #.

Section

Typiquement, le code source d'un programme écrit en assembleur est divisé en deux sections. Il est possible que l'on en voit une troisième un peu plus tard.

La section .data permet de déclarer et d'initialiser les variables du programme. Ici, aucune variable n'est utilisée, la section .data est vide.

La section .text contient le programme en lui même.

Symbole

Le début du programme doit être indiqué par le symbole _start. Un symbole est comme un petit drapeau qui sera planté en mémoire à l'emplacement de la première instruction qui le suit. (ici movl $1, %eax) Les symboles permettent de facilement faire référence à en emplacement en mémoire sans à avoir à connaître son adresse exacte mais en utilisant plutôt le nom que l'on a écrit sur le drapeau.

Vous pouvez utiliser autant de symbole que vous souhaitez pour organiser votre code, seul le symbole _start est obligatoire pour indiquer le début de votre programme au compilateur.

Instructions

movl

La commande movl permet de modifier la valeur d'une case mémoire. (mov pour move, l pour long (?) ce qui fait référence à la taille des données copiées [word].)

Syntaxe : movl source, destination

source peut être :

destination peut être :

int

La commande int interrompt le flot du programme suivant le numéro qui suit cette commande. L'une des interruption les plus utiles est la 0x80, elle permet de réaliser un system call. (int pour interupt)

Syntaxe : int commande

commande est la valeur hexadécimale de la commande a exécuter.

Cette commande s'utilise souvent de la façon suivante.

Les system call permette de réaliser des actions contrôlées par le système d'exploitation. (fin d'un programme, ouverture d'un fichier, et un peu plus de 300 autres) Pour trouver le code d'un système call, vous pouvez rechercher sur internet ou dans le fichier suivant qui les recense toutes !

Pour mettre fin à son programme, la référence du system call à appeler est $1 (system call exit). Il attend comme paramètre un code d'erreur qui sera retourné au système d'exploitation. Celui-ci doit être placé dans %ebx. Par convention, un programme qui se termine sans problème retourne 0 ; tout autre chiffre indique qu'un problème est survenu ou signal un avertissement particulier ou l'état du programme à sa fin. (C'est au bon vouloir du développeur.)

Le programme que nous avons écrit retourne un code d'erreur égale à 1. Pour vous en assurez, vous pouvez exécuter la commande suivante juste après avoir lancé votre programme.

echo $?

Registres

Dans le code précédent, %eax fait référence à un registre. Les registres sont des tous petits bouts de mémoire directement accessible par le micro-processeur. Dans le cadre d'un système 32 bits, les registres peuvent contenir un word.

Registres généraux. Les registres généraux sont des registres que vous pouvez utiliser un peu comme bon vous semble. (Ne sont listés que les registres d'un système 32 bits.)

Registres spéciaux. Les registres spéciaux ne peuvent être utilisés qu'avec certaines commandes ou que dans des usages spécifiques. (Ne sont listés que les registres d'un système 64 bits.)

Remarque

Par défaut, les paramètres des instructions sont interprétées comme des adresse mémoires.

Exercices

Juste avec ces quelques connaissances, voyons ce qu'on peut déjà faire.

~Antoine

13-12-2014


Dive Into ASM

L'assembleur est un langage qui m'a toujours fasciné. Après le langage machine, c'est celui qui est le plus proche du microprocesseur, celui qui nous rappel qu'un ordinateur, ce n'est qu'avant tout qu'une grosse machine dotée d'une bonne mémoire et qui ne sait faire que quelques opérations très simples.

J'ai essayé plusieurs fois de m'y mettre sans jamais aller très loin. Beaucoup de tutoriels donnent un cours complet sur le langage lui-même mais restent parfois très élusifs sur la mise en pratique. Aussi, l'assembleur existe sous différentes saveurs en fonction du système d'exploitation visé et de ses caractéristiques (32 ou 64 bits), et puis deux syntaxes coexistent (Intel et AT&T). En passant d'un tutoriel à un autre, il y a au moins l'une de ces variables qui change, c'est frustrant.

Il y a quelques semaines, j'ai découvert le livre Programming from the Ground Up. La dernière édition date de 2004, cela n'empêche pas que ce livre est parfait pour découvrir ce langage. Comme il est destiné à des personnes qui n'ont jamais programmé, les explications sont claires et complètes. Elles sont en fait parfaitement claires, même si l'on sait déjà programmer.

Ce journal de bord rassemblera mes notes prises au fur et à mesure. Peut être vous permettra-t-il de commencer à jouer avec le langage assembleur. J'en serais en tout cas très heureux. Sachez toute fois que je pense être assez direct dans mes explications. J'écris ces articles en partie pour le moi du futur qui aura envie de redécouvrir l'assembleur après avoir oublié tout ce qu'il savait. Il y a donc quelques notions que je suppose connues du lecteur sur lesquelles je ne pense pas m'étendre. Je pense en particulier au fonctionnement de base d'un microprocesseur, à la notion d'adresse mémoire, ...

Si ces notions sont un peu obscures pour vous (et peut être qu'elles le seront pour mon moi du futur ...), je vous invite à consulter le livre que j'ai mentionné précédemment, Programming from the Ground Up. Il y a aussi le cours Nand2Tetris qui vaut le coup.

Bonne lecture !

~Antoine

PS. J'ai pris le partie de ne pas vous raconter le blabla classique sur ce qu'est ou n'est pas l'assembleur ; je suis sur que si ça vous intéresse, votre moteur de recherche préféré vous aidera à trouver tout ce qu'il faut là dessus.