Pile 32 bits/64 bits

Soyez le premier à donner votre avis sur cette source.

Vue 2 824 fois - Téléchargée 328 fois

Description

Deux petits exemples de code pour montrer aux débutants
(dont je fais parti) le principe de la pile en asm 32 bits
et en asm 64 bits.

ps: mon anti virus n'aime pas trop,je le désactive sinon
il refuse de lancer le prog

Source / Exemple :


Code 32 bits;
-------------

.686
.model flat,stdcall
option casemap:none

includelib kernel32.lib
includelib user32.lib

ExitProcess 	PROTO :DWORD
MessageBoxA 	PROTO :DWORD,:DWORD,:DWORD,:DWORD
MessageBox 	equ <MessageBoxA>

F_esp	proto	;on declare juste F_esp sans indiquer les paramètres
F_ebp	proto	;idem

.code

debut:

push 10		;par ex esp=100=haut de la pile et [100]=10
push 20		;esp=96 et [96]=20
call F_esp	;esp=92 et [92]=adresse de retour=adresse 
                ;de l'instruction qui suit call FA		
;------------------------------------------------
	
push 30		;idem esp=100 et [100]=30
push 40		;esp=96 et [96]=40
call F_ebp	;esp=92 et [92]=adresse de retour
	
	;------------------------------------------------			
		
push 0
call ExitProcess

F_esp	proc	;par ex : A1:dword A2:DWORD
	;ici esp=92 et [92]=adresse de retour
	
;-----------------
;sans utiliser EBP
;-----------------
	
;on récupère les 2 paramètres de F_esp qu'on à pusher avant le call

mov eax,DWORD PTR SS:[esp+8]	;eax=10
mov ecx,DWORD PTR SS:[esp+4]	;ecx=20
	
;on se crée de l'espace pour 2 DWORDS en variables locales
	
sub esp,8	;4*2 dword=8 octets,dword 1 en esp=84,dword 2 en 
                ;esp=88
	
;on fait un calcul bidon et on stocke
;dans les variables locales
	
add eax,60
add ecx,100
mov DWORD PTR SS:[esp],eax		;eax dans A1=[84]
mov DWORD PTR SS:[esp+4],ecx	;ecx dans A2=[88]
	
;....
	
;on nettoie la pile des variables locales crées

add esp,8	;esp=92 et [92]=adresse de retour
	
;on charge eip avec l'adresse de retour par "RET"
;et on nettoie la pile des 2 paramètres pushés avant le call
;par retn "8"  

retn 8	;revient à pop eip + add esp,8 ( A1,A2)
	
F_esp endp

F_ebp	proc	 ;P1:DWORD P2:DWORD

;------------------------
;en utilisant EBP
;------------------------
	
;ici ebp=92 et [92]=adresse de retour

push ebp		;esp=88
mov ebp,esp		;ebp=88
	
;recupération des paramètres pushés
	
mov eax,dword ptr SS:[ebp+12]	;eax=30	(idem que mov eax,dword ptr 
                                ;ss:[esp+8]) 
mov ecx,dword ptr SS:[ebp+8]	;ecx=40 (idem que mov ecx,dword ptr 
                                ;ss:[esp+4])
	
;création de l'espace pour les variables locales
;par ex: B1:DWORD,B2:DWORD,B3:BYTE
	
sub esp,12	;esp=76=bas de la pile
		
;d'ou;
;B1 (dword)est stocké en esp=76,où en ebp-12
;B2 (dword)est stocké en esp=80,où en ebp-8
;B3 (byte) est stocké en esp=84,où en ebp-4 (pile 32 bits=empilement de 
;dword)
	
;nouveau calcul bidon
	
add eax,60
add ecx,100
mov DWORD PTR SS:[ebp-12],eax	;eax dans B1=[esp=76]
mov DWORD PTR SS:[ebp-8],ecx	;ecx dans B2=[esp=80]
mov BYTE PTR SS:[ebp-4],ah	;ah dans B3=[esp=84]
	
;......
	
mov esp,ebp	;esp=88
pop ebp		;esp=92 et [92]=adresse de retour
	
retn 8	;revient à pop eip + add esp,8 (P1,P2)

F_ebp	endp

end debut

///////////////////////////////////////////////////////
code 64 bits
-------------

extrn	__imp_ExitProcess:proc

fonction1	proto
fonction2	proto
fonction3	proto

.code

ALIGN 16
Main		proc

;--------------------------
;appel de fonction1
;--------------------------
;reservation de la pile pour les 4 QWORDS
;obligatoires (dans l'ordre RCX,RDX,R8,R9)
;soit 4  QWORDS*8=32 octets
;on doit aligné rsp sur un multiple de 8
;qui ne soit pas un multiple de 16
;le premier nombre suivant 32 qui rempli cette condition
;est 40 (40/8=5 et 40/16=2.5 ok
;mais par ex 48/8=6 et 48/16=3 d'ou multiple de 8 et de 16=pas bon)

sub rsp,40

mov RCX,0AAAABBBBCCCCDDDDh	;a1
mov RDX,1111222233334444h	;a2
mov R8,5555666677778888h	;a3
mov R9,9999000011112222h	;a4

call fonction1
add rsp,40

;-------------------------------
;appel fonction2
;-------------------------------

sub rsp,40

mov RCX,0AAAABBBBCCCCDDDDh	;b1
mov EDX,0CCCCDDDDh		;b2
mov R8d,2222h			;b3
mov R9d,11h			;b4

call fonction2
add rsp,40

;--------------------------------
;appel fonction3
;---------------------------------
sub rsp,72	;les 4 qwords "obligatoires" RCX,RDX,R8,R9=4*8=32
		;les 4 autres param=4*8=32
                ; ("case" de la pile=toujours qwords)
		;soit 64 octets
		;on s'aligne sur le premier multiple de 8 qui ne soit 
                ;pas un multiple de 16=72

mov RCX,0AAAABBBBCCCCDDDDh	;c1
mov RDX,1111222233334444h	;c2
mov R8,5555666677778888h	;c3
mov R9,9999000011112222h	;c4

mov QWORD ptr[esp+40],1111222233334444h	;c5
mov QWORD PTR[esp+48],0AAAABBBBh	;c6
mov QWORD PTR[esp+56],0CCCCh		;c7
mov QWORD PTR[esp+64],22h		;c8

call fonction3
add rsp,72
;----------------------------------

xor rcx,rcx
call QWORD PTR __imp_ExitProcess

Main 		endp

;------------------------------
ALIGN 16
fonction1	proc	;a1:qword,a2:qword,a3:qword,a4:qword

xor ECX,ECX
xor EDX,EDX
xor R8,R8
xor R9,R9

ret

fonction1	endp
;-----------------------------------
ALIGN 16
fonction2	proc	;b1:qword,b2:dword,b3:word,b4:byte

;recuperation de b3
mov eax,R8d	;b3=ax

;récupération de b4
mov eax,R9d	;b4=al=11h	

xor rax,rax
xor ECX,ECX
xor EDX,EDX
xor R8,R8
xor R9,R9

ret
fonction2	endp
;-----------------------------------
ALIGN 16
fonction3	proc	;c1:qowrd,c2:qword,c3:qword,c4:qword,c5:qword,c6:dword,c7:word,c8:byte

;.......

xor ECX,ECX
xor EDX,EDX
xor R8,R8
xor R9,R9

ret
fonction3	endp
;-----------------------------------

end

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

mpmp93
Messages postés
6709
Date d'inscription
mercredi 13 avril 2011
Statut
Membre
Dernière intervention
28 septembre 2015
4
Bonjour,

Vous venez de ré-inventer ce que faisait le langage FORTH nativement.
http://fr.wikipedia.org/wiki/Forth_%28langage%29

Il existe un processeur dont le langage "assembleur" est le FORTH:
http://en.wikipedia.org/wiki/RTX2010
et
http://www.intersil.com/en/products/space-and-harsh-environment/rad-hard-digital/rh-microprocessors-and-peripherals/HS-RTX2010RH.html#0.html

Votre exemple en assembleur RTX2010:

4 8 *


Et c'est tout!

datasheet du RTX2010:
http://www.da.isy.liu.se/~mj/TSEA20/rtx2000.pdf

J'en ai eu un en main... Il cartonne pour les FFT (Fast Fourier Transform). Le RTX2010 équipe les TGV allemands (ICE) pour le contrôle des moteurs électriques.

A+
cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019

Pas de problème BruNews,je suis là pour apprendre.
je corrige la partie 64 bits et je reposte le tout rapidement.
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
16
Tu as testé tout cela (la partie x64) ?

Désolé mais je n'y vois quasi rien de bon.

Exemple:
;reservation de la pile pour les 4 QWORDS
;obligatoires (dans l'ordre RCX,RDX,R8,R9)
;plus l'adresse de retour RIP
;soit 5 QWORDS*8=40 octets

NIET !!! ce n'est pas le calcul du recul de RSP
RIP est pushé par le 'CALL', n'entre donc pas dans le calcul.
CALCUL:4 param 4*8 32
Ensuite on ajoute à 32 ce qu'il manque pour obtenir un multi de 8 qui ne soit pas multi de 16.
Pourquoi:
A son entrée, toute fonction s'attend à trouver un RSP aligné sur 8 et NON 16. C'est ce qui se passera si tu appliques ce que je viens d'expliquer car c'est bien RIP pushé par CALL qui t'aura mis en 8 non 16. Tout ceci est en autre indispensable pour l'utilisation des registres xmm.
Ex:
aFunc PROC
movdqa [rsp - 24], xmm6
aFunc ENDP

aFunc SAIT que [rsp - 24] est bien ALIGN16 sinon badaboum prog !!!

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.