Revision intra hiver 2016

publicité
Introduction - L'architecture de Von Neumann
•
•
•
•
Inventé par John Von Neumann in 1950
Idée: fonctionnalité traitée comme les données
Suivre une recette (programme)
Appliquer chaque étape au ingrédients (données)
Frigo/Table
Comptoir
?
Recette/
Memory
Input/Output
Programme
Bus
Cuisinier / outils
Processor
1
Introduction - Microprocesseur
• Exécute des instructions simples
– Arithmétique
– Logique
– Branchement (condition)
• Accompli des tâches complexes
• Programmable
• Centre de la majorité des systèmes numériques
– Aussi appelé CPU (Central Processing Unit)
– ou UCT (Unité Centrale de Traitement)
• Types plus spécialisés:
– Microcontrôleur
• Emphase sur autosuffisance et faible coût
– DSP (Digital Signal Processor)
2
Introduction - Mémoire
Memory
Input/Output
Bus
Processor
DIMM:
Dual In-Line
Memory Module
3
4
Introduction - Entrées/Sorties
Memory
Input/Output
Bus
Processor
4
Introduction - Logique électronique
numérique
• Portes logiques
– non (inverseur), et, ou, ou-exclusif …
– anglais: not, and, or, xor …
• Bascule bistable (D)
• Porte 3 états: 0, 1, Z
– Z=Haute impédance (grande résistance)
• Basé sur les transistors
– Plus utilisé présentement: CMOS
– Transistors NMOS et PMOS sur la même puce
MOS = metal oxide semiconductor
•
– « Taille »: 180nm … 65nm … 26nm (réalisé; pas disponible)
5
Introduction - Logique électronique
numérique
Copyright © 2000 by Prentice Hall, Inc.
Digital Design Principles and Practices, 3/e
Copyright © 2000 by Prentice Hall, Inc.
Digital Design Principles and Practices, 3/e
6
Copyright © 2000 by Prentice Hall, Inc.
Digital Design Principles and Practices, 3/e
Table de vérité tampon
inverseur à trois états:
En
1
0
0
IN
*
1
0
| Out
| Z
| 0
| 1
A,B,C pour que la sortie
sera à Z (haute impédance)?
C=0 A=1 B=1
7
Introduction - Périphériques: disques
rigides
© 2007 M. Murdocca and V. Heuring
• Vitesse de rotation constante (RPM)
• Plusieurs plateaux
– Deux surfaces par plateau
• Un bras
– avec une tête par surface
• Chaque surface est divisée:
– Pistes (« track »): cercles concentriques
– Secteur: partie de piste
• Cylindre
– Pistes de toutes surfaces situées à la même distance du centre
• Zone
Source: pcguide.com
– Cylindres ayant le même nombre de secteurs
• Temps d’accès d’une information (moyenne: déplacement de 1/3, rotation de ½)
– Déplacement du bras (tête): « seek time » (moyen: 8ms (disque rapide))
– Temps de rotation: « rotational latency » (latence de rotation moy.: 4ms (7200RPM)
• Taux de transfert au disque:
– Vitesse de rotation * secteurs/piste * données/secteur(=512B/secteur)
8
Introduction - Périphérique: CD
• Initialement fait pour le son:
– 44100 échantillons/seconde * 2 canaux * 16 bits
– 75 secteurs/seconde (donc 2352 octets/secteur)
– Une piste en spirale ; vitesse linéaire constante
• Pour les données:
source: A.S. Tanenbaum, Structured Computer Organization,
– Choix de 2048 (mode1) ou 2324 (mode2 form2) octets/secteur
– + correction d’erreurs
4e édition, Prentice-Hall
• Encodage:
– 1 = transition (trou-à-plat ou plat-à-trou), 0 = constant
uns séparés d’au moins 2 zéros; pas plus de 10 zéros de suite
9
Introduction - Périphériques
• écran
• Affiche les lignes une par une
• Réaffiche l’écran X fois par seconde (50 à 120Hz)
• Données viennent d’une mémoire
• Intensité du pixel: conversion numérique analogique
• interface analogique
10
Architecture
UCT/CPU
Cache
(I+D)
Unité de
contrôle
(pipeline)
Bloc
(d’instructions
instructions
ou de
Cache
données)
Mémoire
principale
instruction
données
R0
R4
R1
R5
R2
R6
R3
R7
données
Cache
données
Page
Mémoire
virtuelle
Registres
Temps d’accès (ns)
0.25-0.5
0.25-25
50-250
5 000 000
Taille
<1KB
< 16 MB
< 215 GB
> 1 TB
Coût
$$$$$
$$$$
$$
$
Source: J. Hennessy, D. Patterson – «Computer Architecture. A quantitative approche», 4-e édition (2006)
11
Architecture - Les niveaux d'abstraction d'un ordinateur
12
Architecture - Instruction Set Architecture (L3)
• Interface entre matériel et logiciel
• Ce que c’est visible pour programmeur
• Consiste en:
– instructions (opérations et la façon que les opérations sont codées)
– informations sur les unités composants (taille, adressage etc.)
– description de registres accessibles (l’ état du processeur)
– contrôle des entrées/sorties
Donc ISA donne au programmeur en assembleur une « image » de la
machine qui inclut le matériel accessible et les instructions qui permettent
la manipulation de données à l’ intérieur du matériel.
13
Architecture des instructions
Source : wikipedia.org
add r1 = r2 + r3
Operand – destination/source
Opcode – code operation, addition ici
14
Architecture des instructions
Nombre d’opérandes spécifiées: 1 à 3 selon le processeur
1: accumulateur ou pile (co-pro Intel x86)
•
1 adresse
add A
acc ←acc + mem[A]
2: une source sert aussi de destination (Intel x86, AVR, …)
•
2 adresses
add A B
EA(A) ←EA(A) + EA(B)
3: destination distincte des deux sources (MIPS, SPARC, …)
• 3 adresses
add A B C EA(A) ←EA(B) + EA(C)
Taille d’instruction
fixe (MIPS – 32 bits, SPARC – 32 bits , AVR(±) – 16 bits
variable (Intel x86, MC68000, …)
15
Architecture - Mémoire
Grand « tableau » de cases ayant chacune une adresse
Lors d’une écriture:
Présenter l’adresse binaire à la puce
Présenter la donnée binaire à la puce
Mettre actif le signal d’écriture
Donnée
Donnée
0
01100111
1
10011100
2
00000000
…
Lors d’une lecture:
Présenter l’adresse binaire à la puce
Mettre actif le signal de lecture
Un certain temps après, la puce répond avec la donnée
Adresse
1023 11110000
Enable
Read/Write
Mémoire
Adresse
16
Architecture - Mémoire
● Ordre placer les octets
– Grosboutiste/groboutien (« big-endian »): gros bout (MSB) à petite
adresse
– Petitboutiste/petitboutien (« little-endian »): petit bout (LSB) à petite
adresse
– Ex: placer deux entiers de 32bits dans une mémoire à mots de
32bits:
– 0x12345678 à l’adresse 0, et 0x123 à l’adresse 4 (vue par le
programme
Adr.
sur
puce
Adr. vue par
prog.
0
0 1 2 3
12 34 56 78
1
4 5 6 7
00 00 01 23
« big-endian »
Adr.
sur
puce
Adr. vue par
prog.
0
3 2 1 0
12 34 56 78
1
7 6 5 4
00 00 01 23
« little-endian »
17
Architecture - la machine de Von
Neumann
La séquence d’opérations pour exécuter un programme
1) Récupérer les instructions de la mémoire
2) Décoder la représentation numérique des instructions
3)Charger les données de la mémoire ou des entrées vers
l’accumulateur
Entrées/
4) Exécuter l’opération correspondante sur
Mémoire
les données
Sorties
5) Sauvegarder le résultat
6) Revenir à 1) et répéter
L’accumulateur est une
petite mémoire proche du
processeur
Unité arithmetiquelogique (ALU)
Accumulateur
Unité de
contrôle
Processeur
18
Architecture - Exécution des instructions
mémoire
Donnée
mémoire
Instruction
Circuit de
contrôle
Mémoire
● Boucle d’exécution:
– Lire la prochaine instruction; pointer vers la suivante
– Chercher les données selon l’instruction
– Exécution de l’opération
Compteur
– Écriture du résultat
d’instructions
Adresse
● Ex. sur architecture à un bus:
Banque de
registres
A
Unité
arith.
(UAL)
C
19
Architecture - Exécution des instructions
-1 bus 32 bits – occupé par un registre à la fois
- MA – le CPU copie l’ adresse mémoire dans MA
- MD – les données sont lues de ou écrites dans
MD
- Le premier opérande ALU toujours en A, le
résultat en C
- Le deuxième opérande vient toujours du bus
- L’informations du bus va toujours en IR et MA
- Un décodeur interprète l’info envoyée au IR
- MA communique l’ adresse à la mémoire et
non au CPU
Source: Heuring&Jordan
20
Architecture - 1 bus
-
Informations sur l’architecture:
ALU doit être capable d’additionner 2 valeurs de 32 bits
ALU doit être capable d’incrémenter l’ entrée B avec 4
Pour lire la mémoire: l’adresse se trouve en MA et les
données sont mises en MD
Le premières 3 étapes (recherche d’instructions) sont le
mêmes pour toutes les instructions – architecture un bus
21
Architecture - 2 bus
– A données qui entrent dans les
registres, B – données qui sortent.
– C=B – fonction d’ALU permettant
les transferts simples
Source: Heuring&Jordan
22
Architecture - Description abstraite vs.
concrète
● RTN (Register Transfer Notation) (source: Heuring&Jordan; pas Atmel)
– A ← B Écrit B dans A
– A[B] Prend le mot B du tableau/mémoire A
– A ‹B› Prend le(s) bits B de A
●n..m Spécifie une plage d’index (pour bits ou mots)
A → B Si A, alors exécuter et retourner B
A#B Concaténation des bits de A et B (A étant de poids fort) (A:B dans Atmel)
A@B Répétition A fois du bit B
: Séparateur parallèle (: pendant le même cycle d’horloge – l’ordre ne compte
pas)
– ; Séparateur séquentiel (; cycles d’horloge successifs – l’ordre est importante)
– := Définition
– Opérateurs arithmétiques et logiques standards…
23
–
–
–
–
Architecture - conversation avec
périphérique
● Certains périphériques demandent de l’attention
● Deux méthodes « d’attente »
– Scrutation (« polling »): aller voir souvent
– Interruption: aller voir lorsqu’on « sonne »
● Étapes d’un interruption
– Un circuit dédié reçoit les requêtes
– Le processeur arrête ce qu’il fait pour les traiter
– Une routine est exécutée par le processeur
– Le processeur reprend où il était
● Attention
– Interruption n’importe où
– Sections critiques: possible d’empêcher les interruptions
24
Architecture - sélection, banque de
registre
●
Supposons un jeu d’instructions à 3 opérandes (abstract RTN):
–
OP ra, rb, rc
⇔ R[ra] ← R[rb] ⊗ R[rc] (où ⊗ est l’opération)
–
op := IR⟨⟨31..27⟩⟩ : ra := IR⟨⟨26..22⟩⟩ : rb := IR⟨⟨21..17⟩⟩ : rc := IR⟨⟨16..12⟩⟩
⟨31..27⟩⟩ ⟨26..22⟩⟩ ⟨21..17⟩⟩ ⟨16..12⟩⟩
5
Activer
écriture
Décodeur
5 vers 32
32
Vers bascules
pour écrire
5
⟨11..0⟩⟩ inutilisés
5
Mulitplexeur
2 vers 1
Select
b/c
5
Décodeur
5 vers 32
Activer
lecture
32
Vers portes
trois-états
●
Contrôle: 3 fils
25
Architecture - Contrôle
Source: Heuring&Jordan
26
Architecture - UAL
● Un circuit par opération logique, puis un MUX
– and, or, xor, not + MUX 4:1
● Un circuit pour toutes opérations « bitwise »
– 16 possibilités d’opérations de 2 entrées booléennes
Table de vérité
– Donc, MUX 4:1
a
b
MUX 4:1
a
résultat
● Un circuit pour ‘plus’ et pour ‘moins’
– A - B = A + (-B)
– En complément à deux: -B = not(B)+1
b
sub/add
n
n
n
additionneur
n+1
27
Architecture - UAL
●
Décaleur de N bits (« Shifter »)
- Pour manipulation de bits – extraire bits individuels dans mots
- Multiplication et division puissances de 2
- A*4 = A<<2
- A/8 = A>>3
- A*5=(A<<2) + A
- A << B (décaler A de B bits vers la gauche, 0 ≤ A < 2N , 0 ≤ B < N)
- Décaleur logique:
– i.e. A<<3
A>>3
11010110 -> 10110000
11010110 -> 00011010
- Décaleur aritmetique:
– i.e. A<<3 11010110 -> 10110000
A>>3
11010110 -> 11111010 (le bit de signe du
nombre initial)
28
Architecture
29
Exercice architecture
IR
IR
IR
32
Q
IR
IR
CLR
re
ct
u
C
E
D
Q
Registres
[0..7]
(soit eax,
ebx, …)
e
Donnée
D
SET
2
ur
r it
éc
IR
Mémoire1
mux
1B
le
Circuit de
contrôle
0
IR
eax:=R[0] : ebx:=R[1] :
ecx:=R[2] : edx:=R[3] :
esi:=R[4] : edi:=R[5] :
ebp:=R[6] : esp:=R[7]
F
Adresse
D
SET
Q
X
EIP
CLR
Q
Q
0
mux
H1
+
0
IR
1
4
mux
A
SET
T
Q
UALY
D
G
Mémoire2
Donnée
CLR
Adresse
L’UAL permet entre autres les opérations suivantes :
0→X : 1→Y : 2→X + Y : 3→X - Y : 4→X << Y :
5→X >> Y ; 6→Y + 4 : 7→Y - 4 : …
30
Exercice architecture
Donnez le RTN concret pour: Memoire2[123+eax] ← ecx
T ← 123;
T ← T + eax;
Memoire2[123+eax] ← ecx;
IR
0
IR
IR
IR
32
SET
Q
IR
IR
CLR
ct
ur
e
C
E
D
Q
Registres
[0..7]
(soit eax,
ebx, …)
e
ur
rit
Donnée
D
2
éc
IR
Mémoire1
mux
1B
le
Circuit de
contrôle
F
Adresse
D
SET
Q
X UALY
EIP
CLR
Q
Q
0
mux
H1
+
T
0
IR
1
4
mux
A
SET
Q
D
G
Mémoire2
Donnée
CLR
Adresse
31
Exercice architecture
b) Donnez le RTN abstrait, pour «MOV %esi, 3(%eax, %ebx, 2)»
Mémoire2[3+eax+ebx*2] ← esi
c) Indiquez comment pourrait être codée en langage machine une
instruction qui fait l’opération en b).
eax:=R[0] : ebx:=R[1] : ecx:=R[2] : edx:=R[3] : esi:=R[4] : edi:=R[5] :
ebp:=R[6] : esp:=R[7]
IR<23..21> = 4 : IR<20..18> = 0 : IR<17..15> = 1 :
IR<14..13> = 1 : IR<12..0> = 3
32
ur
u
rit
re
le
ct
éc
e
IR ← Mémoire1[EIP] : EIP ← EIP + 4 ;
T ← ebx ;
T ← Mémoire2[T] ;
ecx ← T + ecx ;
Après écriture IR⟨12..0⟩=3 : IR⟨14..13⟩=1 : IR⟨17..15⟩=3 : IR⟨20..18⟩=1 : IR⟨23..21⟩=2
A B C D E F G UAL wEIP wIR wT wR
1
1
1
1
1
1
1
1
1
1
0
1
2
1
33
Assembleur - Les données
•
•
•
•
•
•
•
•
•
•
Byte = 1 octet (8 bits) - char
Word = 2 octets (16 bits) - short
Doubleword (dword) = 4 octets (32 bits) - int, long, *
Quadword (qword) = 8 octets (64 bits) - long long
Entiers non-signés de N bits, [0 , 2N-1] - unsigned
Entiers signées de N bits, [-2N-1 , 2N-1-1] - signed
Float = 4 octets (32 bits) - float
Double = 8 octets (64 bits) - double
Temporary float (tfloat) = 10 octets (80 bits) - long double
Chaine de caractères ascii
34
Assembleur - Les données
Etiquette (label)
Type (.word bits16)
.data # directive on est dans le segment données
(comme déclarations)
val: # location etiquette
.word 10, -14, 30 # trois mots
.text # on est dans le segment texte – instructions
assembleur
.global main # mais est publique
main: addi $sp, $sp, -8 # additione immédiate
Valeurs
35
Assembleur - donnés, déclarations
.data
unbyte:
.byte 9,8,0b111
1112
unword:
.word 1,2,10%3
M16[1007]=10mod3=1
unshort:
.short 0x9C, 077
unentier:
.int 52+4, unword-2
.float 12.54
.double 67.34
# espace initialisé, lisible, écrivable
# Si cet espace commence à 1000
# unbyte = 1000
# Mem[1000] = 9, Mem[1001] = 8, Mem[1002] =
# unword = 1003
# M16[1003]=1, M16[1005]=2,
# unshort = 1009
# M16[1009]=9C16, M16[1011]=778
# unentier = 1013
# M32[1013]=56, M32[1017]=1003-2=1001
# M32[1021]=12.54 en IEEE-754 sur 32-bits
# M64[1025]=67.34 en IEEE-754 sur 64-bits
36
Exercice placement de données
.data
debut_data:
a:
.ascii ‘a’
.byte 3, 16
.word 0
.equ c, a - b
.int -2, b + 1
b:
.byte 010, 0b10
.skip 2
fin_data:
0x1000
0x1004
0x1008
0x100C
a : 0x1000
Donnez la valeur de chaque octet en
mémoire à partir de l’adresse
debut_data (incluse), jusqu’à l’adresse
fin_data (non incluse), en hexadécimal.
Le code ASCII de ‘a’ est 0x61.
debut_data 0x1000
Quelles sont les valeurs associées à a,
b, c et fin_data
Octet 0
Octet 1
Octet 2
Octet 3
0x61
0x00
0xFF
00
0x03
0xFE
0x0E
0x08
0x10
0xFF
00
0x02
0x00
0xFF
00
00
b : 0x100D
c : -13
fin_data : 0x1011
37
Assembleur - Instructions
-
-
3 classes:
Déplacement de données mémoire registre
chargement (load) registre<- mémoire
stockage (store) mémoire <- registre
Operation arithmetiques/logiques (UAL)
Addition, shift
Branchement (instruction control flot de donnees)
Branchement, jump, call
38
Assembleur - Les indicateurs (eflags)
15
-
14
NT
13 12
IOPL
•Information
11
OF
10
DF
9
IF
8
TF
7
SF
6
ZF
5
-
4
AF
3
-
2
PF
1
-
0
CF
sur le résultat de la dernière instruction effectuée
― vrai := 1 : faux := 0
― CF := eflags⟨0⟩
carry; retenue/emprunt; débordement non signé
― PF := eflags⟨2⟩
parity; vrai si le nombre de bits à 1 est pair
― AF := eflags⟨4⟩
auxiliary carry; pour le BCD (binary coded decimal)
― ZF := eflags⟨6⟩
zero; vrai si le résultat est zéro
― SF := eflags⟨7⟩
sign; vrai si le résultat est négatif
― DF := eflags⟨10⟩ direction; (DF=faux → inc) : (DF=vrai → dec)
― OF := eflags⟨11⟩ overflow; débordement signé
•Toutes les opérations arithmétiques/logiques modifient eflags
― Les instructions « cmp » et « test » ne modifient que eflags
•Eflag pas modifié par
― Branchements (jmp, j?, call, ret, loop)
― Copies/déplacent de données (mov, xchg, push, pop, lea)
39
Exercice
Quelles seront les valeurs de %al , du ZeroFlag (ZF), du
SignFlag (SF), du CarryFlag (CF) et du OverflowFlag (OF)?
mov $0b00100011,%al
sub $0b01001001,%al
00100011
– 01001001
%al = 11011010
ou
00100011
+ 10110111
= 11011010
ZF = 0 (le résultat n’est pas zéro),
SF = 1 (bit de poids fort est à 1),
CF = 0 (sans retenue ou emprunt)
OF = 0 (le signe du résultat est bon)
40
Assembleur - Transferts de données
•mov
source, destination
destination ← source
•xchg a, b
échange a et b
•lea source, destination
destination ← adr. de source
― « lea » pour « load effective address »
― Source doit être de type mémoire, destination de type registre 32-bits
― Donc: lea dep(%r1,%r2,k), %rd
RTN: R[rd] ← dep+R[r1]+R[r2]*k
― Ex: lea (%ebx,%ecx), %eax
RTN: R[eax] ← R[ebx] + R[ecx]
•push/pop
(voir – Introduction à IA-32)
•pusha
(push all)
push(eax);push(ecx);push(edx);push(ebx);push(esp);push(ebp);push(esi);
push(edi)
•popa (pop all)
edi←pop; esi←pop; ebp←pop; esp←pop; ebx←pop; edx←pop; ecx←pop;
eax←pop
41
Assembleur - Opérations arithmétiques :
additions
•
•
•
•
•
Affectent tous eflags selon le résultat de l’opération
add source, dest
dest ← dest + source (M, R; R, M; R,R)
adc source, dest
dest ← dest + source + CF
sub source, dest
dest ← dest – source
sbb source, dest
dest ← dest – source – CF
Eflag affectés: OF, SF, ZF, PF, CF …
•
cmp source, dest
dest – source (seulement eflag est affecté)
•
neg dest
dest ← 0 – dest (M; R - SF, ZF, PF, CF … )
•
inc dest
dest ← dest + 1 (M; R)
dec dest
dest ← dest – 1 (M; R )
Eflag affectés: OF, SF, ZF, PF …
•
42
Assembleur - Opérations arithmétiques :
multiplications
mul source8
ax ← al * source8 (non signé)
mul source16
dx#ax ← ax * source16
mul source32
edx#eax ← eax * source32
Attention – dans cette forme
source ne peux pas être immédiate
edx dx ne peuvent pas être immédiat
CF et OF si résultat prend plus de place que la source imul
source8
…
(même chose mais signé)
imul source16
…
imul source32
…
imul source, dest
dest ← dest * source
imul const, source, dest
dest ← const * source
const est immédiat; source est registre ou mémoire; dest est registre
43
Assembleur - Instructions logiques
Affectent eflags selon le résultat
OF ← 0 : CF ← 0 : SF ← résultat⟨31⟩ : ZF ← (résultat=0) :
PF ← ((nombre de bits à 1 dans résultat) +1) mod 2
Opérations bit par bit
(A#B#C) ⊗ (D#E#F) = (A⊗D)#(B⊗E)#(C⊗F)
or source, dest
dest ← dest ∨ source
Peut servir à forcer des bits à 1
and source, dest
dest ← dest ∧ source
Peut servir à forcer des bits à 0
xor source, dest
dest ← dest ⊕ source
Peut servir à inverser des bits
Peut servir à mettre à 0 un registre: xor %eax, %eax
44
Assembleur - Instructions de décalage
Affectent eflags (CF, OF, ZF)
CF ← dernier bit sorti
Si source est $1, OF ← résultat<signe> != valeur_décalée<signe>
Opérandes
Source: immédiat ou %cl
Dest: registre ou mémoire (8, 16 ou 32 bits)
Décale d’un maximum de 32 bits
Décale de src5 bits src5 := source<4..0>
shr source, dest – dest#CF ← src5@0 # dest<31..src5-1> Shift right
#
division par 2 ou puissance de 2
sar source, dest – dest#CF ← src5@dest<31> # dest<31..src5-1> Shift
arithmetic right
shrd
source, source2, dest - dest#CF ← source2<src5-1..0> #
dest<31..src5-1>
45
source2 doit être registre
Assembleur - Instructions de décalage
ror source, dest
dest#CF ← dest⟨src5-1..0⟩ # dest⟨31..src5-1⟩
Rotate right
rcr source, dest
dest#CF ← (dest#CF)⟨src5-1..0⟩ # (dest#CF)⟨32..src5⟩
Rotate (through) carry right
shl source, dest
(arithmetic) left
CF#dest ← dest⟨32-src5..0⟩ # src5@0 # Shift
(sal := shl) multiplication par 2 ou puissance de 2
shld source, source2, dest
src5⟩
rol source, dest
CF#dest ← dest⟨32-src5..0⟩ # source2⟨31..32CF#dest ← dest⟨32-src5..0⟩ # dest⟨31..32-src5⟩
Rotate left
rcl source, dest
src5⟩
CF#dest ← (CF#dest)⟨32-src5..0⟩ # (CF#dest)⟨32..33-
Rotate (through) carry left
46
Assembleur - Instructions sur les
indicateurs (contrôle)
stc
clc
cmc
cld
std
pushf
popf
lahf
sahf
cli
sti
CF ← 1
(set carry)
CF ← 0
(clear carry)
CF ←!CF
(complement carry)
DF ← 0
(clear direction, direction positive)
DF ← 1
(set direction, direction négative)
push(eflags) (push flags)
eflags ← pop (pop flags)
AH ← eflags<7..0> (load ah flags)
eflags<7..0> ← AH (store ah flags)
IR ← 0
(clear interrupt request)
IR ← 1
(set interrupt request)
47
Assembleur - Opérations arithmétiques
: divisions
div source8
al ← ax / source8 : (non signé)
ah ← ax mod source8
div source16
ax ← dx#ax / source16 :
dx ← dx#ax mod source16
div source32
eax ← edx#eax / source32 :
edx ← edx#eax mod source32
Attention source – registre en mémoire mais non immédiate
edx, ed ne peuvent pas être immédiat
idiv source8
…
(même chose mais signé)
idiv source16
…
idiv source32
…
N’existe pas: idiv source, dest
48
Exercice lecture d’assembleur
fin_data:
.text
.global main
main:
mov $0x1001, %ebx
mov (%ebx), %ecx
mov $c, %esi
mov b(%esi), %edx
lea b+8(,%edx,2), %edi
mov 0x1000, %dh
mov $0b10100010,%eax
xor $0b01010100,%al
pushl $ici
ici: inc %bh
ret
.data
debut_data:
a:
#0x1000
.ascii ‘a’
.byte 3, 16
.word 0
.equ c, a - b
.int -2, b + 1
b:
#0x100D
.byte 010, 0b10
.skip 2
fin_data:
%al suite à xor, ainsi que la valeur des bits ZF et SF du registre eflags
%al : 11110110
ZF : 0
SF : 1
49
Exercice lecture d’assembleur
.data
debut_data:
a:
#0x1000
.ascii ‘a’
.byte 3, 16
.word 0
.equ c, a - b
.int -2, b + 1
b:
#0x100D
.byte 010, 0b10
.skip 2
fin_data:
a : 0x1000
b : 0x100D
c : -13
fin_data : 0x1011
fin_data:
.text
.global main
main:
mov $0x1001, %ebx
mov (%ebx), %ecx
mov $c, %esi
mov b(%esi), %edx
lea b+8(,%edx,2), %edi
mov 0x1000, %dh
mov $0b10100010,%eax
xor $0b01010100,%al
pushl $ici
ici: inc %bh
ret
%ebx, %ecx, %edx, %esi, et %edi (en hexadécimal) après l’exécution de la routine main
%ebx : 0x1101 %ecx : 0x1003
%edx : 0x106161
%esi : 0Xfffffff3
%edi : 0x2016D7
50
Assembleur - Branchements
•Sans
condition: jmp quelquepart
― quelquepart est un entier/adresse/étiquette
― RTN: R[eip] ← quelquepart
― quelquepart peut aussi être « *opérande »
jmp *%eax
RTN: R[eip] ← R[eax]
jmp *4(%eax) RTN: R[eip] ← M32[4 + R[eax]]
•Conditions: j? quelquepart
― Où ? est le nom de la condition: c, nc, z, nz, o, no, s ns, p, np, a
― Condition sur eflags ou %ecx
― RTN: condition_vrai → (R[eip] ← quelquepart)
•Appel/retour de sous-routine:
― call quelquepart RTN: push(R[eip]) : R[eip] ← quelquepart
51
― ret
RTN: R[eip] ← pop
Assembleur - Conditions
•Toujours
selon indicateurs (sauf cas de %ecx)
― Noms selon: indicateurs, comparaison non signée , comparaison signée
― jecxz/jcxz jump if ecx/cx is zero
condition ecx = 0 ou cx = 0
•Noms selon indicateurs:
― jc
jump if carry
CF = 1 → (R[eip] ← quelquepart)
― jnc
jump if no carry
CF = 0
"
― jz
jump if zero
ZF = 1
― jo
jump if overflow
OF = 1
― jno
jump if no overflow
OF = 0
― js
jump if sign
SF = 1
― jns
jump if no sign
SF = 0
― jp
jump if parity
PF = 1
― jnp
jump if no parity
PF = 0
― jpo
jump if parity odd
PF = 0 (même chose que « jnp »)
52
Assembleur - Conditions
•Comparaison:
cmp y, x
― affecte eflags selon l’opération x-y
•Noms suivant une comparaison non signée: (above/below)
― jb
jump if below
CF = 1
(comme jc)
― jnb
jump if not below
CF = 0
(comme jnc)
― jbe
jump if below or equal CF = 1 ∨ ZF = 1
― jnbe
jump if not below or equal
CF = 0 ∧ ZF = 0
― ja
jump if above
CF = 0 ∧ ZF = 0 (comme jnbe)
― jna
jump if not above
CF = 1 ∨ ZF = 1 (comme jbe)
― jae
jump if above or equal CF = 0
(comme jnb)
― jnae
jump if not above or equal
CF = 1
(comme jb)
― je
jump if equal
ZF = 1
(comme jz)
― jne
jump if not equal
ZF = 0
(comme jnz)
53
Assembleur - Conditions
•Noms
suivant une comparaison signée: (greater/lower)
― jl
jump if lower
SF ≠ OF
― jnl
jump if not lower
SF = OF
― jle
jump if lower or equal SF ≠ OF ∨ ZF = 1
― jnle
jump if not lower or equal
SF = OF ∧ ZF = 0
― jg
jump if greater
SF = OF ∧ ZF = 0
(comme jnle)
― jng
jump if not greater
SF ≠ OF ∨ ZF = 1
(comme jle)
― jge
jump if greater or equal SF = OF
(comme jnl)
― jnge
jump if not greater or equal
SF ≠ OF
(comme jl)
― je
jump if equal
ZF = 1 (comme en non signé)
― jne
jump if not equal
ZF = 0
"
•Comment se rappeler above/below vs. greater/lower
― jb = jc
― « carry » est un débordement non signé
54
Assembleur - Boucles
•Instructions
spéciale: loop, loopz, loopnz
― N’affectent pas eflags
― loop quelquepart ecx ← ecx – 1 ; (ecx ≠ 0) → (eip ← quelquepart)
― loopz quelquepart ecx ← ecx – 1 ; (ecx ≠ 0 ∧ ZF = 1) → (eip ← " )
● Pour « loop while zero »
― loopnz quelquepart
ecx ← ecx – 1 ; (ecx ≠ 0 ∧ ZF = 0) →
(eip ← " )
● Pour « loop while not zero »
55
Exemple while
#repeter.s
.text
.global _start
_start:
xorl %eax,%eax
movl $6,%ecx
repeter:
addl %ecx,%eax
cmpl $36,%eax
jna repeter
# eax = 0
# instructions
# jump si %eax <= 36
movl $1,%eax
xorl %ebx,%ebx
ret
56
Assembleur - Boucles
En C: do b; while(a);
–
En assembleur:
boucle:
# code de b
# code de a
j? boucle
En C: while(a) b;
–
En assembleur:
jmp test_au_debut
boucle:
# code de b
test_au_debut:
# code de a
j? boucle
57
Assembleur - Boucles
En C: for(a; b; c) d;
–
Équivalent au C: (s’il n’y a pas de « continue » dans le corps)
a;
while(b) {
d;
c;
}
En C: break; et continue;
En assembleur:
boucle:
#…
j? break
#…
j? continue
#…
continue:
# (code de l’incrémentation)
# code de la condition
j? boucle
break:
–
58
Exercice
Quel est le contenu du registre %eax à la fin de la sousroutine suivante? Expliquez.
mystere:
mov $4, %eax
boucle:
add %al,%ah
sub $1, %al
jnz boucle
ret
4+3+2+1 = 10; %eax = 0x0A00
59
Assembleur - Directives
●
●
●
Remplissage de mémoire
–
.fill répétitions, NBoctets, valeur(=0)
–
.skip répétitions, valeur
Équivalent à .fill répétitions, 1, valeur
.space synonyme de .skip
Alignement
–
.balign val1, val2(=0 ou nop), val3(=infini)
Aligne sur un multiple de val1 en utilisant val2 pour remplir
Si le nombre d’octet à placer n’est pas > val3
–
.p2align val1, val2, val3
Fait un .balign 2val1, val2, val3
Alignement selon Intel (recommandations)
–
Aligner les données sur des multiples de leur taille
–
Aligner les étiquettes du code, sur 16 octets, si c’est a moins de 8 octets
Étiquette de boucle
Étiquette suit un saut inconditionnel
60
Conventions du C
•
•
•
•
Les variables globales sont dans la section .data
Les variables locales et paramètres sont sur la pile
– En C les paramètres sont empilés de droite à gauche avant le ‘call’
(dépilés au retour du ‘call’)
– L’espace pour les variable est alloué au début de la sous-routine
– On utilise souvent %ebp pour pointer vers ces variables/paramètres
La valeur de retour
– Dans %eax pour les entiers (char/short/int…) et pointeurs (edx:eax pour 8
octets)
– Dans %st(0) pour les float/double (registres larges pour operations point
flotant)
– En mémoire pour les objets/structures
• Le pointeur où placer le résultat est donné par la routine appelante
Registres qu’ une routine peut modifier: %eax, %ecx, %edx
– Doit sauver/restaurer les autres si on les modifies
61
La pile – paramètres, valeurs, variables
Responsabilités “caller” (main)
-
push les paramètres en ordre inverse (le dernier dans la pile le premier)
-
call
-
pop les paramètres (pop ou incrémentation %esp pour les enlever)
-
la valeur de retour en %eax
Responsabilités “callee” (procédure)
-
stocke %ebp d’appeleur dans la pile # prologue procédure push %ebp
-
sauvegarde le %esp courant dans %ebp # prologue procédure mov %esp, %ebp
-
codage, stockage variables locales dans la pile
-
sortie rapide – load %esp de %ebp (sinon pop élément par élément) #épilogue
procédure mov %ebp, %esp # retour aux valeurs initiales (clean up) pile
-
pop ancien %ebp et return – stocke valeur de retour en %eax #épilogue procédure
pop %ebp # retour aux valeurs initiales (clean up) pile
62
Exercice écriture assembleur
Soit la fonction fun qui appelle la routine fun1, qui appelle la
routine fun2, qui appelle la routine fun2, qui appelle la
routine fun3 qui appelle la fonction taille_pile. La fonction
taille_pile retourne le nombre de cadres de pile (stack
frames), la fonction fun incluse, la fonction taille_pile non
incluse. Pour l’exemple donné, la fonction retourne la
valeur 5. Écrire en assembleur la fonction taille_pile qui
retourne le nombre de cadres de la pile. Le %ebp
sauvegardé pour la fonction fun est supposé d’être 0.
Indice : La fonction commence avec son propre %ebp et
trace les anciens %ebp jusqu’au 0.
63
Solution
taillepile:
push %ebp
mov %esp, %ebp
xorl %eax, %eax #eax a 0
movl (%ebp), %ecx # premier ancien ebp sauvegardé
boucle:
cmpl $0, %ecx
je bouclefin
incl %eax
movl (%ecx), %ecx
jmp boucle
#prochain ancien ebp sauvegardé
bouclefin: # compteur déjà en %eax
mov %ebp, %esp
pop %ebp
ret
64
Exercice écriture assembleur
int g(unsigned int x);
int somme(unsigned int n, int *valeurs)
{
int val;
val = g(n) - valeurs[n+1];
if(n > 0) val = val + valeurs[n-1];
return val;
}
Écrivez la sous-routine somme en assembleur.
65
4
somme :
push 4(%esp)
#n
call
g
add
$4, %esp
mov 4(%esp), %ecx
mov 8(%esp), %edx
sub
4(%edx, %ecx, 4), %eax
jecxz
add
faux :
ret
faux
#n
# enlève le paramètre
# int n
# int *valeurs
# val = valeurs[n+1]
# branche si n == 0
-4(%edx, %ecx, 4), %eax
66
Téléchargement