Den Zweck einiger Assembly-Anweisungen verstehen

9

Ich versuche, einen Assembler-Code zu verstehen, und habe es geschafft, das meiste davon zu beenden, außer ein paar Zeilen. Ich bin in der Lage, das meiste zu verstehen, was im Inneren passiert, aber ich bin nicht in der Lage zu verstehen, was (und warum) am Anfang und am Ende des Codes passiert. Kann jemand etwas Licht darauf werfen?

%Vor%

Zerlegte Version:

%Vor%     
Legend 19.11.2010, 18:39
quelle

2 Antworten

27

Der Stapel wächst nach unten . A push subtrahiert vom Stapelzeiger (esp) und ein pop addiert zu esp. Sie müssen daran denken, viel davon zu verstehen.

%Vor%

lea = Effektive Adresse laden

Dies speichert die Adresse der Sache, die 4 Bytes in den Stapel liegt. Da dies ein x86-Code mit 32 Bit (4 Byte Wort) ist, bedeutet dies das zweite Element auf dem Stapel. Da dies der Code einer Funktion ist (in diesem Fall main), sind die 4 Bytes, die sich am Anfang des Stapels befinden, die Rückkehradresse.

%Vor%

Dieser Code stellt sicher, dass der Stapel auf 16 Bytes ausgerichtet ist. Nach dieser Operation ist esp kleiner oder gleich wie vor dieser Operation, also kann der Stack wachsen, was alles schützt, was sich bereits auf dem Stack befindet. Dies geschieht manchmal in main nur für den Fall, dass die Funktion mit einem nicht ausgerichteten Stack aufgerufen wird, was dazu führen kann, dass die Dinge wirklich langsam sind (16 Byte ist eine Cachezeilenbreite auf x86, obwohl 4 Byte Alignment wirklich ist) wichtig hier). Wenn main einen nicht ausgerichteten Stapel hat, wird der Rest des Programms auch.

%Vor%

Da ecx zuvor als ein Zeiger auf das Ding auf der anderen Seite der Rücksprungadresse von dem vorherigen Anfang des Stapels geladen wurde, so bedeutet dies, da dies einen Index von -4 hat, zurück zu der Rückkehradresse für die aktuelle Funktion wird an den Anfang des Stapels zurückgeschoben, so dass main normal zurückkehren kann. (Push ist magisch und scheint in der Lage zu sein, an verschiedenen Stellen im RAM in derselben Anweisung zu laden und zu speichern).

%Vor%

Dies ist meistens der Standardfunktionsprolog (das vorherige war speziell für main). Dies macht einen Stapelrahmen (Bereich zwischen ebp und esp), in dem lokale Variablen leben können. ebp wird so geschoben, dass der alte Stack-Frame im Epilog (am Ende der aktuellen Funktion) wiederhergestellt werden kann.

%Vor%

eax ist der Ort, an dem ganzzahlige Funktionsrückgabewerte gespeichert werden. Dies wird so eingestellt, dass 0 von main zurückgegeben wird.

%Vor%

Dies ist die Funktion Epilog. Es ist schwieriger zu verstehen, aufgrund des seltsamen Stack Alignment Codes am Anfang. Ich habe ein wenig Mühe herauszufinden, warum der Stack diesmal um einen geringeren Betrag als im Prolog angepasst wird.

Wenn es offensichtlich ist, dass dieser bestimmte Code nicht mit Optimierungen kompiliert wurde. Wenn es dort wäre, würde wahrscheinlich nicht viel da sein, da der Compiler sehen kann, dass, selbst wenn es die in Ihrem main aufgeführte Mathematik nicht getan hätte, das Endergebnis des Programms dasselbe ist. Bei Programmen, die tatsächlich etwas tun (haben Nebenwirkungen oder Ergebnisse), ist es manchmal einfacher, leicht optimierten Code zu lesen (-O1 oder -0s Argumente für gcc).

Das Lesen von Assembly, das von einem Compiler generiert wird, ist oft viel einfacher für Funktionen, die nicht main sind. Wenn Sie lesen wollen, um den Code zu verstehen, dann schreiben Sie sich eine Funktion, die einige Argumente benötigt, um ein Ergebnis zu erzeugen, oder das auf globalen Variablen funktioniert, und Sie werden es besser verstehen können.

Eine andere Sache, die Ihnen wahrscheinlich helfen wird, besteht darin, dass gcc die Assemblydateien nur für Sie generiert, anstatt sie zu zerlegen. Das -S -Flag sagt ihm, dies zu erzeugen (aber nicht um andere Dateien zu erzeugen), und benennt die Assembly-Dateien mit einem .s am Ende. Dies sollte für Sie leichter zu lesen sein als die disassemblierten Versionen.

    
nategoose 19.11.2010, 20:06
quelle
6

Ich bin mir nicht sicher, warum der Compiler all diese Sachen macht, aber hier ist, was ich entziffern kann:

%Vor%     
Jens Björnhager 19.11.2010 19:38
quelle

Tags und Links