Instructions

Les instructions que peuvent exécuter un core vont dépendre de son modèle. Il existe deux grandes familles qui se distinguent par le choix des opérations qu'elles permettent :

On s'accorde à dire que le RISC est plus rapide mais consomme plus que le RISC :

Les développement récents tendent à brouiller un peu ces différences, chaque architecture empruntant à l'autre ses points forts (le CISC scinde certaines de ses instructions pour gagner en consommation et le RISC propose quelques instructions complexes pur les optimiser).

De nombreuses personnes pensent que l'avenir est aux puces RISC et que leur utilisation dans les devices mobiles n'est que le début. Par exemple apple et ses nouvelles puces M pour toutes leurs machines, ou encore Angelina Jolie et sa phrase mythique :

"RISC architecture is gonna change everything" (Angelina Jolie parlant de son portable dans Hackers (1995)).

RISK vs CISC et ARM vs x86. Et une comparaison avec le petit dernier RISC-V

Pour la suite de ce cours, nous allons cependant uniquement nous occuper d'architecture x86-64, donc CISC car la majorité des pc en sont équipés.

Registres

Les registres sont la mémoire dont dispose un core. Cette mémoire est très rapide, donc très chère : il n'y en a que peu.

Un registre est un espace mémoire de 64b ou le core stocke les paramètres et les résultats de ses instructions.

Par exemple l'instruction :

ADD RAX, 42

Va ajouter 42 à la valeur du registre RAX puis placer le résultat dans le registre RAX.

On peut aussi :

ADD RAX, RDX

Qui va ajouter la valeur du registre RDX à la valeur du registre RAX puis placer le résultat dans le registre RAX.

Ou encore :

ADD RAX, [RDX]

Qui va ajouter la valeur (64bits) à l'adresse du registre RDX à la valeur du registre RAX puis placer le résultat dans le registre RAX.

Toutes les façons de faire ADD : la commande ADD.

Il y a un petit nombre de registres x86-64. Les registres 64b commencent par R.

Registres généraux

Il en existe 14 de 64b. Ils sont utilisées dans une grande variété de cas.

Paramètres

Déplacement de données

génériques

de R8 à R15 (registres fourre-tout).

Décomposition des registres

Les registres généraux se divisent en bouts plus petits. Par exemple le registre RAX se décompose en :

Instruction pointer

Il s'appelle RIP qui contient l'adresse de la prochaine instruction à exécuter.

Gestion de la pile

Deux registres de gestion de la pile :

Registre d'états (flag)

Le registre RFLAGS est un registre d'états qui permet de rendre compte d'états arrivant en plus de l'instruction.

C'est une structure de donnée de type bit field : chaque état est codé par un bit du registre : si l'état est présent ce bit vaut 1, sinon il vaut 0.

Par exemple si le résultat de l'opération précédente vaut 0, le 6ème bit de ce registre vaut 1 (c'est le zéro flag).

Ces états permettent de faire les instructions if/then/else en laguage machine en utilisant des instructions de saut conditionnels.

Autre registres

Il existe également des registres de segments :

opcode

Chaque instruction possède un code permettant de l'identifier de façon unique. On appelle ceci l'opcode. Il diffère non seulement pour chaque commande mais également pour chaque usage de la commande (chaque usage de la commande ADD aura un opcode différent).

Le passage d'une instruction assembleur à l'opcode n'est pas triviale :

Heureusement, il existe des site pour nous aider :

Utilisez ce site ci-après pour connaître l'opcode de l'instruction ADD RAX, 42 :

Attention au fait qu'il faut que vous soyez en x64, RAX n'étant pas défini en 32bits.

Que fait l'instruction : MOV RAX, 0 ? Et celle ci : XOR RAX, RAX ?

Quel est l'instruction à privilégier ?

solution

Les deux instructions font la même chose, elles place 0 dans RAX. Mais la seconde à un opcode plus court que la première, c'est pourquoi vous verrez souvent la seconde instruction lorsque vous décompilez du code.