2016-07-31 15 views
0

Wenn Sie sowohl die MOV und LEA Anweisungen in der Montage verwenden, was bedeutet es wirklich, wenn jemand schreibt:Baugruppe Arithmetik?

mov DWORD PTR [esp+4], 0x80484c 
    lea eax,[ebp-40] 

Insbesondere dann, wenn sie die Informationen in den Klammern [] schreiben. Ich weiß, dass Lea Adressen bewegt und Inhalte bewegt, aber wenn sie die Adressen in lea oder mov berechnen, wie funktioniert das eigentlich? Ist es das gleiche wie Zeigerarithmetik in C?

+3

'ist es das gleiche wie Zeigerarithmetik in C' - Nein, ist es nicht. Eine umfassende Antwort finden Sie in jeder anständigen x86 Assembly Dokumentation/Buch und frei verfügbar um. –

+0

Beachten Sie, dass es in 'lea' keinen realen Speicherzugriff gibt: Er berechnet lediglich die Adresse des Operanden und speichert sie. Compiler verwenden es manchmal, um nicht signierte Arithmetik auszuführen - allerdings nicht in diesem speziellen Fall, wie es scheint. –

+0

Nicht nur umfassende Antworten finden Sie in der Montagedokumentation, hier finden Sie viele sehr umfassende und klare Antworten mit einer schnellen Suche. –

Antwort

4

lea nicht bewegen Adressen, es die effektive Adresse berechnet und speichert die resultierende Adresse in das Zielregister. Adressberechnungen werden in Maschinensprache mit regulärer Arithmetik und nicht mit C-Zeigerarithmetik durchgeführt.

lea eax,[ebp-40] 

40 subtrahiert von dem Wert in Register ebp und speichert das Ergebnis im Register eax.

mov DWORD PTR [esp+4], 0x80484c 

Ermittelt die Zieladresse durch 4 den Wert Hinzufügen esp im Register enthalten ist, und speichert den Wert 0x80484c, die ganzzahlige 8407116, als 32-Bit-Ganzzahl einnimmt 4 Bytes an dieser Adresse, niedrigstwertiges Byte zuerst.

2

lea berechnet nur einen Ausdruck und speichert ihn in Variable. Es macht eigentlich nichts mit Speicher- oder Speicheradressen, selbst wenn es als 'load effective address' bezeichnet wird.

Zum Beispiel lea eax,[ebp-40] bedeutet eax = ebp - 40.

kann es verwendet werden, um Ausdrücke zu berechnen, die sonst mehrere Anweisungen dauern würde, zum Beispiel:

lea eax, [8 * eax + ebx + 10] 

eax = 8 * eax + ebx + 10 mit einer Anweisung berechnet.

Auf der anderen Seite mov, wenn mit [...] verwendet wird, liest/schreibt etwas von/in den Speicher, so ist es ein bisschen wie mit C-Zeigern.

mov DWORD PTR [esp+4], 0x80484c 

Das spart 32-bit unsigned integer (DWORD) Wert 0x80484c an Speicherplatz esp + 4, also gleich wie folgende pseudo-C:

*((uint32_t*)(esp + 4)) = 0x80484c; 
+0

Also könnten Sie sagen, dass jedes Register ohne irgendwelche Bits/Bytes beginnt, und um Werte in diese Register zu verschieben, müssen Sie diesen Registern Bytes hinzufügen? Wenn ich also ein 32 Bit int in das Register EAX verschieben wollte, müsste ich sagen: mov DWORD PTR [EAX + 4], (32 Bit int)? –

+0

@ JohnConradGeentry Nr.CPU-Register sind nur interne Variablen der CPU. Zum Beispiel ist 'eax' ein 32-Bit-Register und enthält immer einen 32-Bit-Wert, der genau eine 32-Bit-Variable wäre. (Google über X86-Assembly-Register, um mehr zu erfahren.) –

+0

@JohnConradGeenty Um den Wert in ein Register zu verschieben, verwenden Sie 'mov eax, (32-Bit-Wert)'. Ich habe meine Antwort editiert, um zu erwähnen, dass nur mit '[...]' '' mov' 'auf Speicher zugreifen wird. –