myTribu::reb0rn Search Members Help Calendar
Welcome Guest .:: Log In :: Register ::. .:: Resend Validation Email  

Reply to this topicStart new topicStart Poll

> [ASM] La pile ! ( ou stack pour anglophile ), Comment ça marche ?! :p

DarkFantasy

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 684
Member No.: 4
Joined: 21-June 04

Posted: Sep 12 2004, 15:52 PM   Quote Post 

Héhéh je vais tenter de vous expliquer ce que je pense savoir de la pile smile.gif

Préface:

Si vous êtes une fille, et que vous avez appréciées ce tut, merci de bien vouloir me donner un rendez-vous dans l'adresse suivante : darkfantasy_666@hotmail.com ( ok on peut tj rêver hein laugh.gif )

Introduction

Pourquoi apprendre et comprendre l'utilité de la pile ?
Cette question peut paraître bête cependant je vais taché de vous l'expliquer: d'abord il se peut que ne sachez même pas ce qu'est une pile dûe à l'utilisation ( pour moi abusive Langue.gif ) des langages "haut-niveau" une pile est une type de mémoire fonctionnenant sur le principe LIFO ( Last In First Out j'expliquerai plus tard comment elle fonctionne ). Dans les langages "haut-niveau" comme le C/C++ la pile intervient :
  • lorsqu'on fait utilise une variable ( exemple : char cVar; unsigned int dwVar; etc.. )
  • quand on passe des arguments à une fonction
  • lorsqu'il faut retourner à "sur-appelle" ( bref sauvé l'addresse de retour d'une fonction par exemple )
  • sauver des valeurs temporaires mais ceci est assez transparent en "haut-niveau"
  • Peut d'autre moment dont je pense pas ( merci de m'les rappeller Langue.gif )
Fonctionnement & lieu

Comme je l'ai dit toute à l'heure, la pile fonctionne sous le principe du LIFO, ce qui signifie que le dernier élement rentré sera aussi le premier à sortir concretement ça signifie quoi ? Voici en exemple en asm ( désolé Langue.gif partez pas les filles Silence.gif )
CODE

push 8; Met le chiffre 8 sur la pile
push 7; Met le chiffre 7 sur la pile
pop ah; Sort le dernier élement donc 7 et est directement envoyé sur ah ( EAX  en 8bits )
pop al; Sort l'autre élement donc 8 et est directement envoyé sur al ( EAX en 8bits aussi )

J'espère que vous avez un peu près compris smile.gif

Variable & Fonctions

Un dead listing mieux vaut qu'un long disours c'est bien connue biggrin.gif allez hop

QUOTE (IDA (coupé))

.text:00401000    ; ---------------------------------------------------------------------------
.text:00401000
.text:00401000    ; Segment type: Pure code
.text:00401000    ; Segment permissions: Read/Execute
.text:00401000    _text          segment para public 'CODE' use32
.text:00401000                    assume cs:_text
.text:00401000                    ;org 401000h
.text:00401000                    assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00401000
.text:00401000    ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401000
.text:00401000    ; Attributes: bp-based frame
.text:00401000
.text:00401000    fakefunction    proc near              ; CODE XREF: _main+13p
.text:00401000
.text:00401000    arg_0          = byte ptr  8
.text:00401000    arg_4          = word ptr  0Ch
.text:00401000    arg_8          = dword ptr  10h
.text:00401000
.text:00401000 000                push    ebp
.text:00401001 004                mov    ebp, esp
.text:00401003 004                mov    [ebp+arg_0], 0
.text:00401007 004                mov    [ebp+arg_4], 0
.text:0040100D 004                mov    [ebp+arg_8], 0
.text:00401014 004                pop    ebp
.text:00401015 000                retn
.text:00401015
.text:00401015    fakefunction    endp
.text:00401015
.text:00401016
.text:00401016    ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401016
.text:00401016    ; Attributes: bp-based frame
.text:00401016
.text:00401016    fakefunctionptr proc near              ; CODE XREF: _main+27p
.text:00401016
.text:00401016    arg_0          = dword ptr  8
.text:00401016    arg_4          = dword ptr  0Ch
.text:00401016    arg_8          = dword ptr  10h
.text:00401016
.text:00401016 000                push    ebp
.text:00401017 004                mov    ebp, esp
.text:00401019 004                mov    [ebp+arg_0], 0
.text:00401020 004                mov    [ebp+arg_4], 0
.text:00401027 004                mov    [ebp+arg_8], 0
.text:0040102E 004                pop    ebp
.text:0040102F 000                retn
.text:0040102F
.text:0040102F    fakefunctionptr endp
.text:0040102F
.text:00401030
.text:00401030    ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:00401030
.text:00401030    ; Attributes: bp-based frame
.text:00401030
.text:00401030    _main          proc near              ; CODE XREF: start+AFp
.text:00401030
.text:00401030    ptrlong        = dword ptr -18h
.text:00401030    ptrchar        = dword ptr -14h
.text:00401030    ptrshort        = dword ptr -10h
.text:00401030    var3            = dword ptr -0Ch
.text:00401030    var2            = word ptr -8
.text:00401030    var1            = byte ptr -4
.text:00401030
.text:00401030 000                push    ebp
.text:00401031 004                mov    ebp, esp
.text:00401033 004                sub    esp, 24        ; alloue 24octets sur la pile
.text:00401036 01C                mov    eax, [ebp+var3] ; long
.text:00401039 01C                push    eax            ; var3 empilé
.text:0040103A 020                mov    cx, [ebp+var2]  ; short
.text:0040103E 020                push    ecx            ; var2 empilé
.text:0040103F 024                mov    dl, [ebp+var1]  ; char
.text:00401042 024                push    edx            ; var1 empilé
.text:00401043 028                call    fakefunction
.text:00401043
.text:00401048 028                add    esp, 12        ; supprime 12octets sur la pile
.text:0040104B 01C                lea    eax, [ebp+ptrlong] ; long *
.text:0040104E 01C                push    eax
.text:0040104F 020                lea    ecx, [ebp+ptrshort] ; short *
.text:00401052 020                push    ecx
.text:00401053 024                lea    edx, [ebp+ptrchar] ; char *
.text:00401056 024                push    edx
.text:00401057 028                call    fakefunctionptr
.text:00401057
.text:0040105C 028                add    esp, 12        ; en resupprime 12octets le compte est bon la pile est mort smile.gif
.text:0040105F 01C                mov    esp, ebp
.text:00401061 004                pop    ebp
.text:00401062 000                retn
.text:00401062
.text:00401062    _main          endp


Explication Langue.gif tout d'abord le début d'une fonction commence toujours par le PROLOG et finira par l'EPILOG, Nia qu'est-ce c'est ? Et bien appellé aussi StackFrame, cela permet d'allouer une "pile neuve" pour la fonction et de la détruire automatiquement à sa mort elle commence en général par push ebp qui sauve l'addresse de la base de l'ancienne pile puis mov ebp, esp qui permet quant à lui de mettre l'addresse courante de la pile à sa base ( nouvelle pile kwâ ) puis en général on trouve un sub esp, 24 ceci permet d'allouer 24 octets pour la pile ( c'est sub et ça ajoute ? et oui la pile est à l'envers .. Langue.gif ) enfin l'EPILOG fait le contraire bref j'm'attarde pas dessus c'est pas très utile de connaître ça en détail ( ça m'évite de raconter trop de connerie )
Remarque: avec __declspec(naked) on peut empêcher le compilo de faire des PROLOG/EPILOG pour de plus emple info MSDN ClinDOiel.gif
ensuite j'ai fait exprès d'associer des variables normals avec des pointeurs pourquoi ? pour montrer leurs places au sain du lowlevel smile.gif

QUOTE
.text:00401036 01C                mov    eax, [ebp+var3] ; long

Ici on chie une long donc 32bits donc un registre de 32bits et donc eax smile.gif

QUOTE
.text:0040103A 020                mov    cx, [ebp+var2]  ; short

Ici on chie une short donc 16bits donc cx qui est la version 16bits de ecx

QUOTE
.text:0040103F 024                mov    dl, [ebp+var1]  ; char

Ici bah on chie un char donc 8bits donc le reg dl qui est le côté faible en 8bits de edx
Les registres sont comme ceci

EAX
***************************
* AX
*
AH AL

Uniquement vrai pour eax, ebx, ecx, edx.

Remarque: On peut se demander pourquoi on push tout le registre au lieu qu'uniquement un sous-registre ? Et bien j'en sans absolument rien Silence.gif voila Langue.gif

Ensuite pour les pointeurs je fatigue un peu mais tout est en DWORD donc 32bits car une addresse est toujours en 32bits non signés si on type les ptrs dans les langages haut-niveaux c'est simplement pour une question d'optimisation et coréhence entre par exemple un ptr de void * et un char *.

Ensuite on appelle la fonction mais voila vous l'aurez peutêtre remarqué mais les arguments sont données à l'envers ? ( Tain c'est compliqué Langue.gif ) et bien oui en C/C++ les arguments sont données ainsi sauf si on place le mot pascal qui ( à l'honneur de ce langage que j'n'apprécie guére ) on met les arguments à "l'endroit".


Suite prochaienement..Je ne me suis pas relu merci de signaler les fautes si vous avez reussi à lire laugh.gif

____________________
user posted imageuser posted image

 PMEmail PosterUsers WebsiteMSN  Top

Deather

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 683
Member No.: 3
Joined: 28-December 03

Posted: Sep 12 2004, 15:59 PM   Quote Post 

Yép ça j'connais :-p
Par exemple pour additionner deux nombres :
CODE

push eax
push ebx
push ax
mov 7,eax
mov 9,ebx
add eax,abx; je crois que le résultat est mis dans ax de mémoire (loitaine)
pop eax
pop ebx
mov ax,ma_variable
pop ax

ça marcherai ? biggrin.gif

.. oO pourquoi tu prend des pierres ?

 PMEmail Poster  Top

DarkFantasy

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 684
Member No.: 4
Joined: 21-June 04

Posted: Sep 12 2004, 16:25 PM   Quote Post 

Euh tu sauves 2fois ax ( EAX étant le 32Bits de AX qui lui même est composé de AH et AL ) ensuite tu déplaces un registre dans un chiffre ce qui marche pas Langue.gif ensuite l'addition c'est plus ou moins correct enfin tu peux travailler en 8bits enfin le resultat sera pas dans AX mais dans EAX c'est presque pareil puis euh là j'ai du mal tu fais une opération sur EAX puis t'écrases le resultat ( entier comme non >16bits ) avec la valeur d'une variable Langue.gif puis là j'sais plus trop ce qu'il reste dans la pile enfin euh c''est pas vraiment ça désolé Langue.gif
CODE

push eax; sauve eax
mov eax, 7; eax = 7
add eax, 8; Ajoute 8 au reg eax
mov ma_variable, eax; envoie le contenu de eax dans une int ou long
pop eax; récupére eax d'origine

Je voulais faire un tut simple m'enfin là c'est un cas où on sauve le contenue d'un registre avant de l'utiliser cas son ancien contenu va nous reservir ClinDOiel.gif On aurait pu se servir de registre plus bas. Langue.gif

____________________
user posted imageuser posted image

 PMEmail PosterUsers WebsiteMSN  Top

Deather

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 683
Member No.: 3
Joined: 28-December 03

Posted: Sep 12 2004, 17:06 PM   Quote Post 

Lol ça fais un baille que j'm'était intéréssé à l'ASM alors les registres j'les choisi un peu au pif lol ;-)
C'était jsute pour le fun :-)

 PMEmail Poster  Top

DarkFantasy

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 684
Member No.: 4
Joined: 21-June 04

Posted: Sep 12 2004, 17:22 PM   Quote Post 

QUOTE (Deather @ Sep 12 2004, 04:06 PM)
Lol ça fais un baille que j'm'était intéréssé à l'ASM alors les registres j'les choisi un peu au pif lol ;-)
C'était jsute pour le fun :-)

Héhéh c'est le langage le plus fun Langue.gif

____________________
user posted imageuser posted image

 PMEmail PosterUsers WebsiteMSN  Top

DarkFantasy

CALLBACK
***************
Group: Administrateu(r|se)
Posts: 684
Member No.: 4
Joined: 21-June 04

Posted: Sep 17 2004, 23:59 PM   Quote Post 

Up

____________________
user posted imageuser posted image

 PMEmail PosterUsers WebsiteMSN  Top

 1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

Reply to this topicStart new topicStart Poll

 


Top