Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Assembler ::  Assembler und Funktionsaufrufe     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
CCat
Mitglied

Benutzerprofil
Anmeldungsdatum: 23.09.2017
Beiträge: 15
Beitrag CCat Mitglied 14:38:39 06.01.2018   Titel:   Assembler und Funktionsaufrufe            Zitieren

Hallo! =)

Ich beschäftige mich im Moment etwas mit Assembler und habe gerade einige kleine Schwierigkeiten, den generellen Ablauf eines Funktionsaufrufes zu verstehen:

Hier der C-Code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void test_function(int a, int b, int c, int d) {
 
int flag;
char buffer[10]
 
flag = 31337;
buffer[0] = 'A';
 
}
 
int main() {
 
    test_fuction(1,2,3,4);
 
}


Der Assembler sieht so aus:

Assembler:
1
2
3
4
5
6
7
8
9
10
11
push ebp
mov ebp, esp
sub esp,0x18
and esp,0xffffffff0
mov eax,0x0
sub esp,eax
mov DWORD PTR [esp+12], 0x4
mov DWORD PTR [esp+12], 0x3
mov DWORD PTR [esp+12], 0x2
mov DWORD PTR [esp+12], 0x1
call <test_function>


Dann der Code für den Funktionsaufruf:

Assembler:
push ebp
mov ebp, esp
sub esp,0x28
mov DWORD PTR [ebp-12], 0x7a69 ;das ist halt die 31337 in hexadezimal
mov BYTE PTR [ebp-40], 0x41    ;ist das A in ASCII
leave
ret




So, was ich nicht genau verstehe ist, warum macht man:

Assembler:
and esp,0xffffffff0
mov eax,0x0
sub esp,eax


Warum führt man auf dem esp ein logisches und mit dieser Zahl aus und warum schiebt man dann eine 0 ins eax und zieht diese von esp wieder ab?

Zweitens:
Assembler:
sub esp,0x28
mov DWORD PTR [ebp-12], 0x7a69 ;das ist halt die 31337 in hexadezimal
mov BYTE PTR [ebp-40], 0x41    ;ist das A in ASCII

Hier werden ja durch
Assembler:
sub esp,0x28
40 Byte resaviert. Warum 40? Der Int und die 10 char's des Arrays sind doch insgesamt nur 14 Byte, oder?
Und warum schiebe ich die 0x7a69 ab der Stelle [ebp-12] in den RAM und nicht ab Stelle [ebp-4]? Weil ich mache ja "mov ebp, esp", d.h. ich setze ebp auf den zu dem Zeitpunkt aktuellen ESP. Jetzt zeigte der ESP ja zu dem Zeitpunkt auch natürlich auf das Ende des Stacks was hier der Wert ist, nachdem ich
Assembler:
push ebp
ausgeführt habe. Das Heißt der ESP zeigt doch nach
Assembler:
push ebp
praktisch auf die Stelle hinter dem gesicherten EBP? Auf jeden Fall würde ich die 0x7a69 halt dann ab [ebp] schreiben, halt direkt nach dem gesicherten EBP.
Und daher auch, warum schreibe ich das 'A' ab ebp-40?

Kann mir das bitte jemand erklären? =)

Danke!


Zuletzt bearbeitet von CCat am 16:39:59 06.01.2018, insgesamt 4-mal bearbeitet
camper
Moderator

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 7363
Beitrag camper Moderator 23:31:36 06.01.2018   Titel:   Re: Assembler und Funktionsaufrufe            Zitieren

CCat schrieb:
Der Assembler sieht so aus:

Assembler:
1
2
3
4
5
6
7
8
9
10
11
push ebp
mov ebp, esp
sub esp,0x18
and esp,0xffffffff0
mov eax,0x0
sub esp,eax
mov DWORD PTR [esp+12], 0x4
mov DWORD PTR [esp+12], 0x3
mov DWORD PTR [esp+12], 0x2
mov DWORD PTR [esp+12], 0x1
call <test_function>
Ich nehme mal an, dass das kein copy&paste ist. Die Adressen der Funktionsargumente können so ja offensichtlich nicht stimmen.

Mit welchem Compiler auf welchem System mit welchen Compiler-Einstellungen wurde dieser Code erzeugt?

CCat schrieb:
So, was ich nicht genau verstehe ist, warum macht man:

Assembler:
and esp,0xffffffff0
mov eax,0x0
sub esp,eax


Warum führt man auf dem esp ein logisches und mit dieser Zahl aus und warum schiebt man dann eine 0 ins eax und zieht diese von esp wieder ab?
*Man* macht nicht, der Compiler hat sich in diesem speziellen Fall dazu entschieden, diesen Code zu erzeugen. Das and dürfte dazu dienen, den Stack auf 16 Byte auszurichten - gcc macht das z.B. einmalig in main, um dann ohne weiteren Aufwand mit automatischen SSE-Variablen umgehen zu können. Der Zweck des mov eax+sub erschließt sich daraus nicht; es könnte sich evtl. um Padding handeln, um Debugging zu erleichtern.

CCat schrieb:
Zweitens:
Assembler:
sub esp,0x28
mov DWORD PTR [ebp-12], 0x7a69 ;das ist halt die 31337 in hexadezimal
mov BYTE PTR [ebp-40], 0x41    ;ist das A in ASCII

Hier werden ja durch
Assembler:
sub esp,0x28
40 Byte resaviert. Warum 40? Der Int und die 10 char's des Arrays sind doch insgesamt nur 14 Byte, oder?
Und warum schiebe ich die 0x7a69 ab der Stelle [ebp-12] in den RAM und nicht ab Stelle [ebp-4]?
Der Compiler ist nicht gezwungen, Variablen direkt aufeinander folgend anzuordnen. Insbesondere um Arrays herum wird bei ausgelassener Optimierung gerne etwas Platz gelassen, um Bereichsüberschreitungen erkennen zu können.
C++ Forum :: Assembler ::  Assembler und Funktionsaufrufe   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.