Add first part of ASM course
This commit is contained in:
parent
e7967137c1
commit
71a4811ac7
1 changed files with 190 additions and 0 deletions
190
content/secu_logicielle/3_assembleur_approfondissement/index.md
Normal file
190
content/secu_logicielle/3_assembleur_approfondissement/index.md
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
---
|
||||||
|
title: "Sécurité logicielle : L'assembleur - approfondissement"
|
||||||
|
date: 2023-02-01
|
||||||
|
tags: ["assembleur", "intel"]
|
||||||
|
categories: ["Sécurité logicielle", "Cours"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Un premier exemple
|
||||||
|
|
||||||
|
Prenons `IP` comme compteur et `A` , `B`, `C` et `D` comme registres.
|
||||||
|
|
||||||
|
```asm {linenos=true}
|
||||||
|
0x00: mov $1, A
|
||||||
|
0x05: mov $2, B
|
||||||
|
0x0a: mov $3, C
|
||||||
|
0x0f: add A, B
|
||||||
|
0x10: cmp B, C
|
||||||
|
0x11: jz zero
|
||||||
|
0x12: mov $41, A
|
||||||
|
0x17: jmp end
|
||||||
|
0x18: zero:
|
||||||
|
0x18: mov $42, A
|
||||||
|
0x1d: end:
|
||||||
|
```
|
||||||
|
|
||||||
|
La première colonne représente le compteur d'instruction, nous pouvons vois que
|
||||||
|
chaque *instruction prend 5 octets*.
|
||||||
|
|
||||||
|
Ligne 4, la seconde opérande de l'instruction `add` est aussi le résultat
|
||||||
|
|
||||||
|
Ligne 5, l'instruction `cmp` fait une comparaison, en fait il fait une
|
||||||
|
soustraction des deux opérandes. Si le résultat de cette sourtraction (et dons
|
||||||
|
que les opérandes sont égales) alors l'instruction `jz` (*jump zero*) réalisera
|
||||||
|
un saut vers l'étiquette `zero`.
|
||||||
|
|
||||||
|
## Le langage
|
||||||
|
|
||||||
|
### Les registres
|
||||||
|
|
||||||
|
Il étaient de 8 bits à l'origine et nommés `A`, `B`, `C` et `D`, lors du passage
|
||||||
|
en 16 bits, ils se sont appelés `Ax`, `Bx`, `Cx`, `Dx` (pour *extended*). Lors
|
||||||
|
du passage à 32 bits ils sont passé à `eAx`, `eBx`, `eCx`et `'eDx`. Enfin ils
|
||||||
|
sont passé à `rAx`, `rBx`, `rCx` et `rDx` pour la version 64 bits.
|
||||||
|
|
||||||
|
Lors de ce cours, nous utiliseront principalement les versions 32 bits.
|
||||||
|
|
||||||
|
### Les suffixes d'instructions
|
||||||
|
|
||||||
|
Toute comme pour les registres, il existe des version de certaines instructins
|
||||||
|
en fonction de la taille des opérandes :
|
||||||
|
|
||||||
|
* `movb` : 8bits
|
||||||
|
* `movb` : 16 bits
|
||||||
|
* `movl` : 32 bits
|
||||||
|
* `movq` : 64 bits
|
||||||
|
|
||||||
|
### Les usages
|
||||||
|
|
||||||
|
Il existe plusieurs type de registres en fonction de leur usage
|
||||||
|
|
||||||
|
* registres **généraux** : `rAx`, `rBx`, ...
|
||||||
|
* registres **d'indexation** : `RSI` (source) et `RDI` (destination)
|
||||||
|
* registres supplémentaire 64 bits : de `R8` à `R15`
|
||||||
|
|
||||||
|
Nous en verrons d''autre un peu plus tard.
|
||||||
|
|
||||||
|
### Flags de résultats
|
||||||
|
|
||||||
|
C'est un registre de 32 bits, chaque bit correspond à un drapeau spécifique :
|
||||||
|
|
||||||
|
Les 16 premier bits repente les *flags* :
|
||||||
|
|
||||||
|
position | flag | fonction
|
||||||
|
---------|------|----------
|
||||||
|
0 | CF | Carry flag
|
||||||
|
2 | PF | Parity flag
|
||||||
|
4 | AF | Adjust flag
|
||||||
|
6 | ZF | Zero flag (si le résultat est 0)
|
||||||
|
7 | SF | Sign flag (valeur de bit de poids fort)
|
||||||
|
8 | TF | Trap flag
|
||||||
|
9 | IF | Interrupt enable flag
|
||||||
|
10 | DF | Direction flag (sens de lecture d'une chaine de caractère)
|
||||||
|
11 | OF | Overflow flag (positionné en cas d'overflow)
|
||||||
|
12 13| IOPL | IO privilege number
|
||||||
|
14 | NT | Nested tag flag
|
||||||
|
|
||||||
|
Et les 16 suivants les *eflags*:
|
||||||
|
|
||||||
|
position | flag | fonction
|
||||||
|
---------|------|----------
|
||||||
|
16 | RF | Resume flag (Défini la réponse CPU pour la reprise à l'exception pour
|
||||||
|
debug)
|
||||||
|
17 | VM | Virtual 8086 mode
|
||||||
|
18 | AC | Alignement check
|
||||||
|
19 | VIF | Virtual interrupt flag
|
||||||
|
20 | ID | CPUID flag (possibilité d'utiliser le CPUID)
|
||||||
|
21-31 | Réservé
|
||||||
|
|
||||||
|
### Les instructions
|
||||||
|
|
||||||
|
#### Addition / soustraction / incrémentation / décrémentation
|
||||||
|
|
||||||
|
* `add <src> <dest>` : addition de `<src>` et `<dst>`, positionnement du
|
||||||
|
résultat dans `<dst>`
|
||||||
|
* `sub <src> <dst>` : soustraction de `<src>` et `<dst>`, positionnement du
|
||||||
|
résultat dans `<dst>`
|
||||||
|
* `inc <val>` : incrémenter `<val>`
|
||||||
|
* `dec <val>` : décrémenter `<val>`
|
||||||
|
* `neg <val>` : renvoie le complément à deux de `<val>`
|
||||||
|
|
||||||
|
```asm
|
||||||
|
movl $20 %rax # rax = 15
|
||||||
|
addl $10 %rax # rax = rax + 10 = 25
|
||||||
|
subl $7 %rax # rax = rax - 7 = 18
|
||||||
|
incl %rax # rax += 1 = 19
|
||||||
|
decl %rax # rax -= 1 = 19
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Division / Multiplication
|
||||||
|
|
||||||
|
* `mul <src>` : multiplication de `%eax` par `<src>`, `%eax` est choisi en dur,
|
||||||
|
le résultat est écrit sur deux registres `%edx` et `%eax`. `mul` retroune un
|
||||||
|
résultat **non signé**.
|
||||||
|
* `imul` : multiplication comme précédement, mais le résultat est cette fois
|
||||||
|
**signé**
|
||||||
|
* `div <dst>` : divise le nombre contenu dans `%eax` et `%edx` par `<dst>`. Le
|
||||||
|
quotien sera positionné dans `%eax` et le reste dans `%edx`. Le résultat est
|
||||||
|
**non signé**.
|
||||||
|
* `idiv <dst>` : division comme précédement mais cette fois le résultat est
|
||||||
|
**signé**.
|
||||||
|
|
||||||
|
```asm
|
||||||
|
movl $0 %edx
|
||||||
|
movl $8 %eax
|
||||||
|
movl $2 %ebx
|
||||||
|
divl %ebx # %eax = %edx.%eax / %ebx remainer : %edx
|
||||||
|
|
||||||
|
movl $0 %edx
|
||||||
|
movl $8 %eax
|
||||||
|
movl $2 %ebx
|
||||||
|
mull %ebx # %eax = %ebx * %eax
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Shift, rotate
|
||||||
|
|
||||||
|
On parle ici de décalage de bits que se soir à gauche (multilication par 2
|
||||||
|
puissance X) ou à droite (division par 2 puissance X).
|
||||||
|
|
||||||
|
* `shl <n> <dst>` : décalage à gauche de `<dst>` de `<n>` bits (`<dst> << n`).
|
||||||
|
* `shr <n> <dst>` : décalage à droite de `<dst>` de `<n>` bits (`<dst> >> n`).
|
||||||
|
|
||||||
|
Ces deux instructions sont **non signées**, les versions **signées** sont `sal`
|
||||||
|
et `sar`.
|
||||||
|
|
||||||
|
* `sol <n> <dst>` : applique une rotation de `n` bits vers la gauche de `<dst>`
|
||||||
|
* `sor <n> <dst>` : applique une rotation de `n` bits vers la droite de `<dst>`
|
||||||
|
|
||||||
|
```asm
|
||||||
|
movl $0xa %eax
|
||||||
|
rol $0x2 %eax # 00001010 -> 00101000 = 0x28
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Opération bit à bit
|
||||||
|
|
||||||
|
* `and <src> <dst>` : réalisation de l'opération `<src> & <dst>`,
|
||||||
|
positionnement de résultat dans `<dst>`
|
||||||
|
* `or <src> <dst>` : réalisation de l'opėration `<src> | <dst>`, positinnement
|
||||||
|
du résultat dans `<dst>`
|
||||||
|
* `xor <src> <dst>` : réalisation de l'opėration `<src> ^ <dst>`, positinnement
|
||||||
|
du résultat dans `<dst>`
|
||||||
|
* `not <dst>` : réalisation de l'opération `<~dst>` et poitionnement du résultat
|
||||||
|
dans `<dst>`
|
||||||
|
* `cmp <1> <2>` : réalisation de l'opération `<1> - <2>`, le résultat n'est pas
|
||||||
|
affecté mais les drapeaux OF, ZF AF, CF PF son positionné en fonction du
|
||||||
|
résultat.
|
||||||
|
|
||||||
|
#### Instruction de saut
|
||||||
|
|
||||||
|
Certaines de ces instructions on plusieurs notations possibles.
|
||||||
|
|
||||||
|
* `jmp <addr>` : saut vers l'adresse `<addr>` sans condition
|
||||||
|
* `ja <addr>` : saut vers l'adresse `<addr>` si la comparaison au dessus donne
|
||||||
|
comme résultat *strictement supérieur à*
|
||||||
|
* `jae <addr>` : saut vers l'adresse `<addr>` si la comparaison au dessus donne
|
||||||
|
comme résultat *supérieur ou égal à*
|
||||||
|
* `jnae <addr>` : saut vers l'adresse `<addr>` si la comparaison au dessus donne
|
||||||
|
comme résultat *strictement inférieur à* (not above or equal) -- peut être
|
||||||
|
aussi `jng` (not greater)
|
||||||
|
* `jz <addr>` : saut vers l'adresse `<addr>` si la comparaison au dessus donne
|
||||||
|
comme résultat *égal à*
|
Loading…
Add table
Add a link
Reference in a new issue