Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Merci
Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Merci
Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Merci
Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Bonjour,
Tout d'abord, je ne suis pas certain d'être dans le bon groupe et m'en excuse
si c'est le cas.
Soit un programme simple en C, que je désassemble:
$ gdb -q a.out
(gdb) list
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i < 10; i++)
7 {
8 printf("Hello World!n");
9 }
10 }
(gdb) disas main
Dump of assembler code for function main:
0x08048384 <main+0>: lea ecx,[esp+0x4]
0x08048388 <main+4>: and esp,0xfffffff0
0x0804838b <main+7>: push DWORD PTR [ecx-0x4]
0x0804838e <main+10>: push ebp
0x0804838f <main+11>: mov ebp,esp
0x08048391 <main+13>: push ecx
0x08048392 <main+14>: sub esp,0x14
0x08048395 <main+17>: mov DWORD PTR [ebp-0x8],0x0
0x0804839c <main+24>: jmp 0x80483b1 <main+45>
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
0x080483ae <main+42>: inc DWORD PTR [ebp-0x8]
0x080483b1 <main+45>: cmp DWORD PTR [ebp-0x8],0x9
0x080483b5 <main+49>: jle 0x804839e <main+26>
0x080483b7 <main+51>: mov ecx,DWORD PTR [ebp-0x4]
0x080483ba <main+54>: leave
0x080483bb <main+55>: lea esp,[ecx-0x4]
0x080483be <main+58>: ret
End of assembler dump.
(gdb)
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0. Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
--> Est-ce du à une option de compilation de gcc? J'ai seulement
utilise gcc -g prog.c.
gcc -v
Lecture des spécification à partir de
/usr/lib/gcc/i486-slackware-linux/4.3.3/specs
Target: i486-slackware-linux
Configuré avec: ../gcc-4.3.3/configure --prefix=/usr --libdir=/usr/lib
--enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,java,objc --enable-threads=posix
--enable-checking=release --with-system-zlib --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --with-gnu-ld --verbose --with-arch=i486
--target=i486-slackware-linux --build=i486-slackware-linux
--host=i486-slackware-linux
Modèle de thread: posix
gcc version 4.3.3 (GCC)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0.
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Une comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0.
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Une comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
J'ai quelques questions:
Tout d'abord je suis surpris de la structure du programme. <main+17>:
On met EBP-8 à 0.
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur.
Une comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
C'est comme cela qu'est compilé la structure de contrôle while (ou for);
c'est même la manière standard de le faire (avec des analyseurs
descendants). Entre autres, cela permet de traiter «correctement» le cas
for(i ; i<10; i--)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
L'instruction push a deux effets : faire une place en haut de la pile,
et copier une valeur dans cette place créée; l'instruction mov[esp],...
ne fait que la seconde partie.
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
C'est comme cela qu'est compilé la structure de contrôle while (ou for);
c'est même la manière standard de le faire (avec des analyseurs
descendants). Entre autres, cela permet de traiter «correctement» le cas
for(i ; i<10; i--)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
L'instruction push a deux effets : faire une place en haut de la pile,
et copier une valeur dans cette place créée; l'instruction mov[esp],...
ne fait que la seconde partie.
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Puis on jump en fin de programme ou la comparaison
est faite. On remonte en <main+26> pour faire la boucle réelle.
C'est comme cela qu'est compilé la structure de contrôle while (ou for);
c'est même la manière standard de le faire (avec des analyseurs
descendants). Entre autres, cela permet de traiter «correctement» le cas
for(i ; i<10; i--)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
L'instruction push a deux effets : faire une place en haut de la pile,
et copier une valeur dans cette place créée; l'instruction mov[esp],...
ne fait que la seconde partie.
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Ca ferait 2 sauts par boucle en moyenne, alors qu'avec le code généré
par le compilo, 1 saut par boucle en moyenne. C'est évidemment plus
performant.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
0x080483a6 <main+34>: call 0x80482b4
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il faut reconnaître que de nos jours, le code généré par
les compilos et beaucoup plus obscur qu'avant, mais il y a souvent une
bonne raison derrière (surtout pour un exemple aussi simple).
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Ca ferait 2 sauts par boucle en moyenne, alors qu'avec le code généré
par le compilo, 1 saut par boucle en moyenne. C'est évidemment plus
performant.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il faut reconnaître que de nos jours, le code généré par
les compilos et beaucoup plus obscur qu'avant, mais il y a souvent une
bonne raison derrière (surtout pour un exemple aussi simple).
Pourquoi n'avons nous pas en fait une mise à 0 de la valeur. Une
comparaison. Si inférieur ou égale, alors on jumpe à l'affiche
d'HelloWorld, puis un jump en début, ou on incrémente etc.. Si
la valeur est = à 10, alors on jump en fin de programme.
Ca ferait 2 sauts par boucle en moyenne, alors qu'avec le code généré
par le compilo, 1 saut par boucle en moyenne. C'est évidemment plus
performant.
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
0x080483a6 <main+34>: call 0x80482b4
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il faut reconnaître que de nos jours, le code généré par
les compilos et beaucoup plus obscur qu'avant, mais il y a souvent une
bonne raison derrière (surtout pour un exemple aussi simple).
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Et moi qui ne comprenait pas ou était passé mon printf, c'est gcc
qui réécrit le code?
Merci
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Et moi qui ne comprenait pas ou était passé mon printf, c'est gcc
qui réécrit le code?
Merci
printf est remplacé par puts, car GCC croît savoir que c'est mieux.
Et moi qui ne comprenait pas ou était passé mon printf, c'est gcc
qui réécrit le code?
Merci
Le 11-03-2010, Alexandre Bacquart a écrit :Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
$ echo -n 'Hello World!' | wc -c
12
Sans doute ces douze octets?
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
Ok0x080483a6 <main+34>: call 0x80482b4
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
ok. Il est possible de demander à gcc de ne pas faire ce genre
d'optimisations?
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Ok, merci.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il existe des docs abordables? (Genre pas le pavé de 5000pages de chez
intel)
Le 11-03-2010, Alexandre Bacquart <tek512@free.DELETEME.fr> a écrit :
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
$ echo -n 'Hello World!' | wc -c
12
Sans doute ces douze octets?
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
Ok
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
ok. Il est possible de demander à gcc de ne pas faire ce genre
d'optimisations?
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).
Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Ok, merci.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il existe des docs abordables? (Genre pas le pavé de 5000pages de chez
intel)
Le 11-03-2010, Alexandre Bacquart a écrit :Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
$ echo -n 'Hello World!' | wc -c
12
Sans doute ces douze octets?
0x080483a1 <main+29>: push 0x8048480
Pousse l'adresse de la chaîne sur la pile (4 octets en l'occurrence).
Ok0x080483a6 <main+34>: call 0x80482b4
Appel de printf() (en fait, optimisé avec un puts() plus rapide car
l'opération est simple).
ok. Il est possible de demander à gcc de ne pas faire ce genre
d'optimisations?
0x080483ab <main+39>: add esp,0x10
Restauration de la pile de 16 octets (les 12 réservés + les 4 de la chaîne).Pourquoi est-ce qu'il n'y a pas un simple
mov DWORD PTR [esp],0xXXXXXXX avec XXXXXXX l'adresse contenant ma
chaîne "Hello World" suivi d'un call à la fonction printf ?
La convention d'appel du puts() en question qui doit sûrement faire le
minimum (l'appelant devant gérer lui-même la pile, ces conventions
d'appels ont un nom, genre __cdecl ou autres, c'est un peu vieux pour
moi désolé). Sans doute également qu'à ce moment, la pile est alignée
sur 16 octets, et le code veille à ce que ça reste le cas pour la
performance.
Ok, merci.
Se plonger un peu dans les docs du CPU cible devrait répondre à toutes
ces questions.
Il existe des docs abordables? (Genre pas le pavé de 5000pages de chez
intel)
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
Réserve 12 octets sur la pile. Convention d'appel et/ou alignement ?...
Le 11-03-2010, Antoine Leca a écrit :Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
C'est ce que j'ai du mal à comprendre, justement.
Le 11-03-2010, Antoine Leca <root@localhost.invalid> a écrit :
Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4 <puts@plt>
0x080483ab <main+39>: add esp,0x10
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
C'est ce que j'ai du mal à comprendre, justement.
Le 11-03-2010, Antoine Leca a écrit :Je ne comprends pas non plus cette série d'actions:
0x0804839e <main+26>: sub esp,0xc
0x080483a1 <main+29>: push 0x8048480
0x080483a6 <main+34>: call 0x80482b4
0x080483ab <main+39>: add esp,0x10
Tu remarqueras que le "sub" et le "add" ci-dessus ne sont pas
équilibrés: la différence (4, la taille en octets d'un mot) est
justement là pour balancer le 1er effet de l'instruction push.
C'est ce que j'ai du mal à comprendre, justement.
L'idée est que GCC analyse le premier paramètre de printf. Ceci permet
de détecter les bogues de format évidents, mais aussi d'optimiser
lorsqu'on utilise printf
L'idée est que GCC analyse le premier paramètre de printf. Ceci permet
de détecter les bogues de format évidents, mais aussi d'optimiser
lorsqu'on utilise printf
L'idée est que GCC analyse le premier paramètre de printf. Ceci permet
de détecter les bogues de format évidents, mais aussi d'optimiser
lorsqu'on utilise printf