Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Επειδη εχω μπερδευτει αρκετα θέλω να μου πειτε αν το stack frame της main που καλει μια συναρτηση ειναι σωστο ετσι οπως το εχω κανει

 

η συναρτηση ειναι αυτη

void MyFunction3(int x, int y, int z)
{
  int a, int b, int c , int d;
  ...
  return;
}

 _______HIGH__________
 esp--> local0
        local1
        local2
        local4
  ebp->  ebp    
       returnAdd
       1th argum    
       2th argum
       3th argum
       _________
     main stack frame
_______LOW_______________

Δημοσ.

esp + sizeof(local) = epb <=> ebp - sizeof(local) = esp

int foo(int v1,int v2,int v3);

int main()
{
	foo(0x11,0x22,0x33);
	return -0;
	
}
int foo(int v1,int v2,int v3)
{
	int a = 0xaa;
	int b = 0xbb;
	int c = 0xcc;

	int *_ebp = 0, *_esp = 0;

	_asm mov dword ptr [_ebp], ebp
	_asm mov dword ptr [_esp], esp;
	printf("esp:\t%x\tebp:\t%x\n",_esp,_ebp);
	for(int i = 0; i < 11; i++)
		printf("esp+%d\t(addr:%x)\tval:\t%x\n",i,(_esp+i),*(_esp+i));
	return 0;

}

output

esp:    21f934  ebp:    21f94c
esp+0   (addr:21f934)   val:    cc
esp+1   (addr:21f938)   val:    bb
esp+2   (addr:21f93c)   val:    aa
esp+3   (addr:21f940)   val:    21f94c
esp+4   (addr:21f944)   val:    21f934
esp+5   (addr:21f948)   val:    5
esp+6   (addr:21f94c)   val:    21f960
esp+7   (addr:21f950)   val:    9c109e
esp+8   (addr:21f954)   val:    11
esp+9   (addr:21f958)   val:    22
esp+10  (addr:21f95c)   val:    33

Δημοσ.

Επειδη εχω μπερδευτει αρκετα θέλω να μου πειτε αν το stack frame της main που καλει μια συναρτηση ειναι σωστο ετσι οπως το εχω κανει

 

η συναρτηση ειναι αυτη

void MyFunction3(int x, int y, int z)
{
  int a, int b, int c , int d;
  ...
  return;
}
 _______HIGH__________

 esp--> local0

        local1

        local2

        local4

  ebp->  ebp    

       returnAdd

       1th argum    

       2th argum

       3th argum

       _________

     main stack frame

_______LOW_______________

 

 

 

ισχυει οτι ebp+12= esp ;

Γιατί δεν δοκιμάζεις να δεις τι παίζει ?

 

void myf(int x, int y, int z)
{
	int a, b, c, d;
	a = 9;
	b = 12 + x;
	c = 15 + y;
}

int main()
{
	myf(1,2,3);
	return 5;
}
% gcc -Wall -O0 -S -m32 -masm=intel tmp.c
main:
	push	ebp
	mov	ebp, esp
	sub	esp, 12
	mov	DWORD PTR [esp+8], 3
	mov	DWORD PTR [esp+4], 2
	mov	DWORD PTR [esp], 1
	call	myf
	mov	eax, 5
Κοιτώντας το κομμάτι της main έχουμε ότι μετακινήθηκε ο esp κατά 12 για να κάνει χώρο και η τιμή 1 είναι στην διεύθυνση του esp ενώ η τιμή 2 στην esp+4 άρα έχουμε

arg1

arg2

arg3

 

myf:
push	ebp
	mov	ebp, esp
	sub	esp, 16
	mov	DWORD PTR [ebp-4], 9
	mov	eax, DWORD PTR [ebp+8]
	add	eax, 12
	mov	DWORD PTR [ebp-8], eax
	mov	eax, DWORD PTR [ebp+12]
	add	eax, 15
	mov	DWORD PTR [ebp-12], eax
Ερχόμαστε στην συνάρτηση. Εδώ βλέπουμε ότι αφαιρέθηκε από τον esp 16 ώστε να γίνει χώρος για τις 4 τοπικές μεταβλητές μας. Η έκφραση a = 9 μεταφράστηκε σε ebp-4 οπότε το a βρίσκεται σε εκείνη τη θέση. Μετά βλέπουμε ότι το όρισμα x είναι στη θέση ebp+8 ενώ η τοπική b είναι στην θέση ebp-8 και ομοίως το όρισμα y είναι στη θέση ebp+12 ενώ η τοπική c βρίσκεται στη θέση ebp-12.

 

Άρα αν γράψουμε διαφορετικά τα παραπάνω έχουμε:

 

ebp = esp + 16

 

....

ebp-12 : c

ebp-8 : b

ebp-4 : a

 

ebp+8 : x

ebp+12 : y

....

 

Δηλαδή αυτό που σου έγραψε ο παπί.

 

Φυσικά ο compiler μπορεί να επιλέξει μεγαλύτερο alignment από το ελάχιστο που ορίζει το ABI αν κρίνει ότι έτσι είναι καλύτερα οπότε να έχουμε διαφορετικές τιμές.

 

Edit: Αν προσθέσω στον gcc την παράμετρο -fomit-frame-pointer ώστε να μην χρησιμοποιήσει τον ebp τότε ο κώδικας που παίρνουμε είναι ίσως ακόμη πιο εύκολος στην ανάγνωση (φυσικά αν στο παραπάνω που έγραψα όπου ebp έβαζα esp+16 θα παίρναμε ακριβώς αυτό που φαίνεται παρακάτω).

myf:
	sub	esp, 16
	mov	DWORD PTR [esp+12], 9
	mov	eax, DWORD PTR [esp+20]
	add	eax, 12
	mov	DWORD PTR [esp+8], eax
	mov	eax, DWORD PTR [esp+24]
	add	eax, 15
	mov	DWORD PTR [esp+4], eax
	add	esp, 16
esp+4 : c

esp+8 : b

esp+12 : a

 

esp+20 : x

esp+24 : y

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...