# [ASM] Kit de base

## Introduction

Le **langage d'assembleur** est le langage le plus bas-niveau et le plus proche du langage machine.

Cependant, contrairement aux autres langage, chaque **architecture** possède son **jeu d'instruction** et donc son propre langage d'assembleur.

Ce cours traitera essentiellement de l'architecture **Intel** et peut-être **AT&amp;T**.

[![image.png](https://wiki.neopipe.fr/uploads/images/gallery/2023-12/scaled-1680-/YZAimage.png)](https://wiki.neopipe.fr/uploads/images/gallery/2023-12/YZAimage.png)

## Installation d'un assembleur (nasm)

#### Linux

Pour installer **nasm** sur Debian :

```bash
sudo apt install -y nasm build-essential
```

## Registres  


#### Registres de données

Un registre de données permet de stocker 16 bits soit 2 octets avec les bits forts placés à gauche et les bits faibles à droite.

<table border="1" id="bkmrk-nom-raccourcis-nom-c" style="border-collapse: collapse; width: 100%; height: 149px;"><colgroup><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col><col style="width: 33.3333%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**Nom raccourcis**  
</td><td class="align-center" style="height: 29.8px;">**Nom complet**  
</td><td class="align-center" style="height: 29.8px;">**Fonction**  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">AX  
</td><td class="align-center" style="height: 29.8px;">Accumulator  
</td><td class="align-center" style="height: 29.8px;">Opérations arithmétiques et d'entrées/sorties.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">BX  
</td><td class="align-center" style="height: 29.8px;">Base register  
</td><td class="align-center" style="height: 29.8px;">Adressage mémoire.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">CX  
</td><td class="align-center" style="height: 29.8px;">Count register  
</td><td class="align-center" style="height: 29.8px;">Compteur de boucle.  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">DX  
</td><td class="align-center" style="height: 29.8px;">Data register  
</td><td class="align-center" style="height: 29.8px;">Extension d'AX.</td></tr></tbody></table>

#### Registre d'états

Ce type de registre contient des flags permettant de suivre des états.

## Sections

#### Data

C'est ici que nos constantesseront définies dans le code commae dans l'exemple ci-dessous :

```
SECTION .data
msg     db      'Hello world!', 0Ah
```

<p class="callout info">La valeur **0A** correspond au caractère **\\n** et le **h** spécifie qu'il s'agit d'une valeur hexadécimale.  
</p>

#### Text

C'est ici que nous définissons le point d'entrée (le label qu'il faut lancer pour démarrer le programme) :

```
SECTION .text
global _start
```

## Convention d'appel

Voici la liste des registres et leur utilité lors de l'appel à vos fonctions :

<table id="bkmrk-arch-syscall-nr-retu"><thead><tr><th class="align-center">arch</th><th class="align-center">syscall NR</th><th class="align-center">return</th><th class="align-center">arg0</th><th class="align-center">arg1</th><th class="align-center">arg2</th><th class="align-center">arg3</th><th class="align-center">arg4</th><th class="align-center">arg5</th></tr></thead><tbody><tr><td class="align-center">arm</td><td class="align-center">r7</td><td class="align-center">r0</td><td class="align-center">r0</td><td class="align-center">r1</td><td class="align-center">r2</td><td class="align-center">r3</td><td class="align-center">r4</td><td class="align-center">r5</td></tr><tr><td class="align-center">arm64</td><td class="align-center">x8</td><td class="align-center">x0</td><td class="align-center">x0</td><td class="align-center">x1</td><td class="align-center">x2</td><td class="align-center">x3</td><td class="align-center">x4</td><td class="align-center">x5</td></tr><tr><td class="align-center">x86</td><td class="align-center">eax</td><td class="align-center">eax</td><td class="align-center">ebx</td><td class="align-center">ecx</td><td class="align-center">edx</td><td class="align-center">esi</td><td class="align-center">edi</td><td class="align-center">ebp</td></tr><tr><td class="align-center">x86\_64</td><td class="align-center">rax</td><td class="align-center">rax</td><td class="align-center">rdi</td><td class="align-center">rsi</td><td class="align-center">rdx</td><td class="align-center">r10</td><td class="align-center">r8</td><td class="align-center">r9</td></tr></tbody></table>

## Libc

En architecture Intel x86, selon la convention d'appel, nous devons procédé comme suit pour afficher **"Hello world"** à l'écran :

```
_start:
        MOV eax, 4   ; Appel à SYS_WRITE (OPCODE 4 définit dans la libc)
        MOV ebx, 1   ; La valeur 1 correspond à la sortie standard STDOUT
        MOV ecx, msg ; Met le contenu de la constante msg dans le registre ecx
        MOV edx, 13  ; Indique la taille de la chaîne de caractère incluant le null byte (ici 13)
        INT 80h      ; Lance une interruption de la libc pour exécuter nos instructions
```

Voici comment fermer un programme proprement avec la libc :

```
_start:
        ; Close program
        MOV eax, 1 ; Appel à SYS_CLOSE dans la libc (OPCODE 1) 
        MOV ebx, 0 ; Code de retour 0
        INT 80h
```

## Les jeux d'instructions

<table border="1" id="bkmrk-instructions-descrip" style="border-collapse: collapse; width: 100%; height: 378.2px;"><colgroup><col style="width: 50.0618%;"></col><col style="width: 50.0618%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**Instructions**  
</td><td class="align-center" style="height: 29.8px;">**Descriptions**  
</td></tr><tr style="height: 46.6px;"><td class="align-center" style="height: 46.6px;">**MOV**  
</td><td class="align-center" style="height: 46.6px;">Déplace une valeur dans un registre sous le format suivant : MOV dst, src  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**CALL**  
</td><td class="align-center" style="height: 29.8px;">Fait appel à une subroutine (fonction)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**INT**  
</td><td class="align-center" style="height: 29.8px;">Fait une interruption (pour appeler la libc)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**PUSH**  
</td><td class="align-center" style="height: 29.8px;">Pousse une valeur sur la stack  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**POP**  
</td><td class="align-center" style="height: 29.8px;">Retire une valeur de la stack (format LIFO)  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**SUB**  
</td><td class="align-center" style="height: 29.8px;">Effectue une soustraction entre deux adresses  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**ADD**  
</td><td class="align-center" style="height: 29.8px;">Effectue une addition entre deux adresses  
</td></tr><tr style="height: 29.8px;"><td class="align-center" style="height: 29.8px;">**CMP**</td><td class="align-center" style="height: 29.8px;">Compare deux valeurs</td></tr><tr style="height: 46.6px;"><td class="align-center" style="height: 46.6px;">**JE**  
</td><td class="align-center" style="height: 46.6px;">"Jump if Equal". Se rend sur la routine ou le label indiqué si les deux valeurs comparées sont identiques.  
</td></tr><tr><td class="align-center" style="height: 46.6px;">**JZ**  
</td><td class="align-center" style="height: 46.6px;">"Jump if the Zero flag is set". Se rend sur la routine ou le label indiqué si le flag zero est définit.  
</td></tr><tr><td class="align-center">**JMP**  
</td><td class="align-center">Saute à la routine ou au label mentionné.   
</td></tr><tr><td class="align-center">**INC**</td><td class="align-center">Incrémente une valeur ou une adresse.</td></tr><tr style="height: 46.6px;"><td class="align-center">**RET**</td><td class="align-center">Définit la fin d'une fonction.</td></tr></tbody></table>

## Arguments

Les arguments sont passés sur la stack de sorte à ce que les derniers éléments posés sur la stack soit le **nombre d'argument**, l**e nom de l'exécutable**, le **premier argument**, le **deuxième** etc.