.           ____                 _________          .
       _    __  |__  \   __   __  _  |____  ___| _  _____   __     ___
      | |  / _\ / _|  | /  \ |  \| |  /  _||| | | ||_   _| /  \   / __|
      | |_|  _/ \ \  / | || ||     |  \ \| || | | |  | |  | || |  \ \
      |___|\__/|__/| \ | || || |\  |__/ /| || |_| |  | |  | || |__/ /
                |  |  | \__/ |_| |_____/ | | \___/   |_|   \__//___/
      +         |____/_/ |  _ _          |_|             .
                  _  / _ | | | |  _____             
   .             | | \___|\ \_/\ |_   _| .                     .
                 | |   |_  ||_  |  | |               .     +
       _  _   __ | |__ |_  ||_  |__| |   __   _  _   ___   _
      | \| | /  \|____||__/ |__// _|_|  /  \ | \| | /   \ | |  +          +
      |    || || ||    ||  |  || | ___ | || ||    ||  |  || |
      | |\ || || || |\ ||  _  || ||_  || || || |\ ||  _  || |__
      |_||_| \__/ |_||_||_| |_| \____/  \__/ |_||_||_| |_||____|    
  +     .                          .                        0x00
       -+-                               .
        '                               .

                   .
      ___________ /|___________________________________________
     /                                                         \
    | Pourquoi jouer à Call of Duty ou MineCraft quand          |
    | tu peux apprendre des trucs trop b4d455 avec Denis Salem? |  .
     \__________________________________________________________/__|\___
                                     /                                  \
                                    |  https://denissalem.tuxfamily.org  |
                                     \__________________________________/


Frustré par l'éducation national, et le flou pédagogiques des internets je rédige
cet eZine en solo pour la postérité (mais aussi un peu pour la bonne cause).
Puisse ce release t'être utile, ô lecteur.

 ______________________________________________________________________________
|                                                                              |
| I N D E X                                                                    |
|______________________________________________________________________________|
        |                                                            |
        | 0x00 ASM : Ton premier programme ne sera pas un HelloWorld |
         \___________________________________________________________|

  ______________________________________________________
 /                                                      \
| ASM : Ton premier programme ne sera pas un HelloWorld  |
 \_  ___________________________________________________/
   /'
__0x00__

On va parler ici exclusivement d'assembleur linux pour processeur x86_64,
architecture largement répendu sur la plupart des ordinateurs.
Par ailleurs nous ne nous reposerons que sur la suite gcc lors des différentes
étapes de la compilation.

Commençons avec un code über simple.

.text
	.global _start
		_start:
			movl	$9,%ebx
			movl	$1,%eax
			int	$0x80

Et ouais morray. Rien qu'avec les six  lignes ci-dessous,  y à de quoi tenir un
consortium. Alors un Hello world... Tu pense bien...

Avant d'expliquer que fait chaque ligne nous allons assembler et exécuter tout ça.
Par convention,  l'extension d'un nom de fichier source est ".s". Copiez les six lignes de  code
ci-dessus dans un fichier vierge. Genre "demo1.s". Ensuite, dans un terminal:

[l33t@nonagon asm]$ as demo1.s -o demo1.o
[l33t@nonagon asm]$ ls demo* -l
-rw-r--r-- 1 l33t l33t 696 30 mars  19:53 demo1.o
-rw-r--r-- 1 l33t l33t 168 30 mars  19:53 demo1.s
 _______________________________________________________________________
|                                                                       |
| /!\ N'oublie pas de te reporter au manuel pour en savoir plus sur as. |
|_______________________________________________________________________|

Cette première étape consiste à produire des objets qui serons ensuite lié pour finalement obtenir
un executable. L'option -o de as permet de spécifier le nom de fichier de sortie.

[l33t@nonagon asm]$ ld -o demo1 demo1.o
[l33t@nonagon asm]$ ls -l demo*
-rwxr-xr-x 1 l33t l33T 664 30 mars  19:57 demo1
-rw-r--r-- 1 l33t l33t 696 30 mars  19:53 demo1.o
-rw-r--r-- 1 l33t l33t 168 30 mars  19:53 demo1.s

Nous  obtenons finalement  un fichier exécutable. Genre pour de vrai.  Sans plus
tarder, découvrons ce que fais notre exécutable.Un truc sensationnel,assurément.

[l33t@nonagon asm]$ ./demo1 
[l33t@nonagon asm]$

Bon. Et ben c'est pas folichons tout ça. Mais nous savons que tout programme retourne
systématiquement une valeur entière. Généralement zéro, si le programme s'est terminé correctement. Sinon un code
d'erreur qu'il est possible d'intercepter. Voyons ça.

[l33t@nonagon asm]$ ./demo1 
[l33t@nonagon asm]$ echo $?
9
[l33t@nonagon asm]$

Notre premier programme ne fais en fait strictement rien, sinon retourner 9. Il est interressant de noter
que les instructions pour... ne rien faire constituent quand même un exécutable de 664 bytes.
Un scandale sur lequel nous reviendrons plus tard.
Notre programme ne produit pas d'erreurs et retourne sciemment un entier non nul.

Examinons le code précédent et agrémentons le de quelque commentaires.
Ceux sur une unique ligne commence par "//" et ceux qui en nécessitent
plusieurs commence avec "/*" et se termine avec "*/".

.text // Debut de la section ".text".

       .global _start /* On indique à as que le label "_start" doit être visible
                      pour tous les autres objets. */

		_start:	/* Définition du label "_start". Toutes les instructions
                        qui  suivent  constituent  le corps  du label jusqu'à la 
                        prochaine définition. */

			movl	$9,%ebx // On place  les  valeurs  immédiates 9
			movl	$1,%eax // et 1 dans les  registres eax et  ebx

			int	$0x80 /* Appel de l'interuption logiciel numéro
                                      128 */


La directive ".text" indique le début d'une section du même nom. Cette section
contient les instructions du programme et uniquement les instructions. Il n'est
pas possible d'y stocker des valeurs ou d'y réserver de l'espace mémoire.

La directive global indique que le label "_start" doit être accessible depuis
les autres objets.

On définit ensuite un label. Le nom d'un label peut-être constitué de n'importe quel caractère
alpha-numérique ainsi que des caractères '_', '.' et '$'.
La notion de label est très importante.
Lors de l'exécution d'un programme, le processeur se déplace linéairement dans
celui-ci. C'est à dire qu'il lit une instruction, l'exécute, passe à la suivante
et ainsi de suite. Pour se faire le processeur utilise le registre RIP (EIP pour 
les architectures 32bits) qui repère l'adresse de l'instruction courante. Une fois
l'exécution de cette instruction terminé RIP est automatiquement incrémenté. Dans
la majorité des cas on souhaite controler le fil d'exécution, par exemple lorsque
l'on veut faire une boucle, dans ces cas là on modifie manuellement RIP.

Lors du processus de
compilation, le label sera automatique convertie en une adresse qu'il sera alors
possible de stocker dans RIP.
La définition d'un label est donc important parce qu'elle permet de situer une portion
de code pour y "sauter" quand cela est nécessaire.

Dans notre cas le nom du label n'est pas choisit au hasard, c'est le nom par défaut
du point d'entrée du programme. Ainsi la première instruction du programme sera

	movl $9, %ebx
	
Le saut à la ligne marque la fin de l'instruction. Une instruction peut avoir
une ou plusieur opérandes. Dans la syntax AT&T on place la source AVANT la
destination.

L'instruction movl sert à copier une valeur vers un emplacement
qui peut être un registre on une zone mémoire. Ainsi dans notre exemple,
on place successivement les valeurs immédiates 9 et 1, respectivement, dans
les registres ebx et eax.

Une valeur immédiate est indiqué par le caractère '$', tandis qu'un registre
est préfixé par '%'.

La dernière instruction int interrompt le programme et réalise un appel système,
il s'agit de passer la main à une fonction du noyau, puis de reprendre le programme
là où il en était. Pour faire simple l'opérande de l'instruction int

* voir instruction handler / ISR

  _________________________________________________
 /                                                 \
| Documentation de référence et sources à consulter |
 \_  ______________________________________________/
   /'
__0x__
	Assembleur
		- http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html/
        	- http://sourceware.org/binutils/docs/as/
        	- http://lwn.net/Articles/531148/
		- http://www.bravegnu.org/gnu-eprog/linker.html