Last part of advance assembly course

This commit is contained in:
Yorick Barbanneau 2023-02-20 01:13:50 +01:00
parent 52b9dd8b1a
commit 007d11fc95

View file

@ -9,7 +9,7 @@ categories: ["Sécurité logicielle", "Cours"]
Prenons `IP` comme compteur et `A` , `B`, `C` et `D` comme registres.
```asm {linenos=true}
```asm {linenos=inline}
0x00: mov $1, A
0x05: mov $2, B
0x0a: mov $3, C
@ -282,3 +282,125 @@ impactés**.
cmpl %eax %ebx # %ebx - %eax
cmovgel $1 %edx # si %ebx > ebx (res > 0) alors %edx = 1
```
### Diverses instruction
* `nop` : ne fait rien à part incrémenter le *pointeur d'instruction*. Elle
peut servier à remplir un espace mémoire afin d'éviter de décaller le
restrant du code.
* `halt`: met en pause le CPU
### Travail sur les flottants
Les flotants ont une longueur de *32bits*, les doubles de *64bits*, le
processeur lui les traite sur *80bits* :
* **un bit** de signe
* **15 bits** d'exposants
* **64 bits** de mantisse
Pour information, nombre = mantisse = 10^exposant.
Le processeur dispose de 8 registres (`st0` à `st7`). Leurs accès ne se fait pas
directement mais via `push` / `pop`
ils sont gérés dans une unité à part , qui dispose aussi des ses propres *flags*
sur *16bits*. Les 6 premiers bits sont réservés aux exceptions:
position | flag | fonction
---------|------|----------
0 | IE | Invalid Operation
1 | DE | Denormalized Operand Exception
2 | FE | Zero Divide Exception
3 | OE | Overflow Exception
4 | UE | Underflow Exception
5 | PE | Precision Exception
Voici les suivants:
position | flag | fonction
---------|------|----------
7 | ES | Error Summary Status
8 9 10 14 | C1-C4 | Condition Code
11 12 13 | TOP | Top of stack pointer
15 | B | FPU busy
#### Les instructions
Le FPU dispose de ses propres instructions par exemple:
* `fadd`, `faddp` : addition flotante :
```asm
faddp # Ajouter st1 à st0
fadd a # Ajouter a à st0
fadd a b # Ajouter a à b
```
* `fsub`, `fsubp`: soustraction flottante
* `fmul`, `fmulp`: multiplication flottante
* `fdiv`, `fdivp`: division flottante
* `fchs` : changement de signe (`st(i)`)
* `fabs`: retourne la valeur absolue (`st(i)`)
* `fsqrt`: retourne la racine carré (`st(i)`)
* `fsin`, `fcos` retourne le sinus, le cosinus (`st(i)`)
* `fcomi`: compare l'opérande avec `st0`
```asm
fcomi st2
```
* `fcmovb`, `fcmove`, `fcmovbe`: move si en dessous, egal, en dessous ou égal
### SSE (Streaming SIMD Extentions)
C'est un ensemble de 70 instructions ajoutées au processeurs Intel en 1999, 8
registres supplémentaires sont implémentés : `xmm0` à `xmm7` d'une longueur de
*128bits*. La version 64 bits ajoute 8 registes de plus (`xmm8` à `xmm16`).
#### Instruction
Voici quelques exemples de mnémonique spécifiques à cette partie:
* `movss` qui permet de déplacement, deux opérandes la source (adresse ou
registre `xmm`) et une destination (resitre `xmm`).
* `addss`: additions, s'utilise comme `movss`.
* `subss`, `mulss`, `divss`: respectivement soustrasction, multiplication et
division. Ces opération acceptent les même opérandes que `movss`.
### Les appels systèmes en assembleur
Pour passer en mode noyau, nous pouvons utiliser une interruption spécifique :
`0x80`, le numéro d'appel système doit être positionné dans `%eax` et les
paramètres dasn `ebx`, `ecx`, `edx`, `esi` et `edi`. La valeur de retour est
positionnée dans `eax`.
En version *32bits* l'appel se fait via `int 0x80`. La version *64 bits* dispose
de l'instruction `syscall`.
```asm
.data
# Notre message et sa taille, elle nous sont nécessaire pour appeler
# notre appel système
msg:
.asciz "Hello World\n"
len = . - msg
.text
.globl main
main:
# placement de nos paramètres dans nos différents registres
movl $len, %edx
movl $msg, %ecx
movl $1, %ebx
# numéro de l'appel système sys_write dans eax
movl $4, %eax
# Et lancement de notre interruption
int $0x80
# Relançons un appel système pour exit, avec 0 comme paramètre
movl $0, %ebx
movl $1, %eax
int $0x80
```