Bonjour,
Première question, je me demandais où pointait $eip lorsqu'on arrive à la fin de la fonction main (ret).
Il y a quelque chose qui me chagrine avec gcc, je ne comprend pas pourquoi lorsque je compile une simple source ( int main(){} ) avec gcc sous une debiane j'obtiens :
version gcc 4.0.4 20060507 (Debian 4.0.3-3)
alors que sous fedora core, j'obtiens pour le même code un truc plus compliqué avec des instructions vraiment inutiles mais qui au final revient à exactement à la même chose :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 ;prologue push %ebp mov %esp,%ebp ;épilogue pop %ebp ret
gcc 4.1.1 20060525 (Red Hat 4.1.1-1)
Pourquoi faire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 ;prologue 0x08048354 <main+0>: lea 0x4(%esp),%ecx ;on sauvegarder l'addresse de la pile + 4 (correspond à l'adresse de retour theoriquement) 0x08048358 <main+4>: and $0xfffffff0,%esp ;on reserve un espace (entre 0 et 16 octets) dans la pile ;alignement de la pile ? 0x0804835b <main+7>: pushl 0xfffffffc(%ecx) ; on empile ecx - 4 soit l'adresse la pile a la base ; cette valeur n'est même pas dépilé dans l'epilogue 0x0804835e <main+10>: push %ebp ;sauvegarde du pointeur de frame 0x0804835f <main+11>: mov %esp,%ebp ;nouveau pointeur de pile 0x08048361 <main+13>: push %ecx ;on empile ecx (contient donc ancien adresse esp + 4) [le corp de la fonction] ;épilogue 0x08048362 <main+14>: pop %ecx ; (qui contient ancienne adresse esp + 4) 0x08048363 <main+15>: pop %ebp ; on réstaure le pointeur de frame 0x08048364 <main+16>: lea 0xfffffffc(%ecx),%esp ; esp <- ecx-4 soit la l'ancienne valeur de esp ; ; là je me demande alors l'utilité de l'instruction du prologue : 0x0804835b <main+7>: pushl 0xfffffffc(%ecx) ; => équivalent de leave 0x08048367 <main+19>: ret ; eip restauré
alors qu'on peut aussi simplement faire(ou alors peut etre que je ne comprend pas du tout la syntaxe AT&T, mais je crois bien que c'est équivalent) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 0x08048354 <main+0>: lea 0x4(%esp),%ecx 0x08048358 <main+4>: and $0xfffffff0,%esp 0x0804835b <main+7>: pushl 0xfffffffc(%ecx)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 0x08048354 <main+0>: mov %esp,%ecx 0x08048358 <main+4>: and $0xfffffff0,%esp 0x0804835b <main+7>: pushl %ecx
Partager