2016-12-08 3 views
0

Lets sagen, dass ich eine PROC in My Assembler-Code haben wie so:Dynamische Variablenerstellung in der Baugruppe? (X86 Assembly)

.CODE 
PROC myProc 
MOV EAX, 00000001 
MOV EBX, 00001101 
RET 
ENDP myProc 

Ich möchte 1 MOV in das EAX-Register, und 13 in das EBX-Register in meinem Verfahren bewegen, aber ich Ich möchte zwei Variablen lokal zu meinem PROC erstellen, var a den Wert 1 zuweisen und var b den Wert 13, und von dort MOVing [a] in EAX und [b] in EBX. Ich habe schon viele Ideen dazu hatte, vielleicht Platz für die Variablen auf dem Stapel zu schaffen, oder so etwas wie:

.CODE 
PROC myProc 
PUSH ESP 
PUSH EBP 
MOV ESP, 00000001 
MOV EBP, 00001101 
MOV EAX, [ESP] 
MOV EBX, [EBP] 
ENDP myProc 

Aber noch ist nicht wirklich dynamische Variable Schöpfung, ich bin nur das Schreiben und Lesen von Daten zurück und zwischen den Registern. Im Wesentlichen versuche ich herauszufinden, wie man eine Variable in Assembly zur Laufzeit erstellt. Ich würde jede Hilfe schätzen.

+0

Ihr zweites Beispiel ist Unsinn. Wenn Sie dem Stapelzeiger eine Konstante zuweisen, haben Sie Ihre einzige Referenz auf den Platz verloren, an den Sie ESP und EBP gedrückt haben. Außerdem wird 'mov eax, [001]' nur bei einer schlechten Adresse einen Fehler machen. Ich sehe auch keine Register-zu-Register-Bewegungen in Ihrem zweiten Beispiel, also IDK, was Sie denken, dass es tut, aber es ist nicht "* Schreiben und Lesen von Daten hin und her zwischen Registern. *" –

+0

Wenn Sie dynamischen Speicherplatz möchten zum Speichern einiger Werte, für kleine Dinge (bis zu wenigen kiB), können Sie normalerweise diesen Platz auf dem Stapel reservieren, das ist, was C tut. Zu Beginn von PROC kann eine der Prolog-Anweisungen "sub esp, " sein, und vor "ret" stellst du das 'esp' (das diesen Raum freigibt) wieder her. Dazwischen kann man es mit '[esp + <0 .. size-1 offset>]' ansprechen, obwohl dafür normalerweise das 'ebp' verwendet wird. Wenn Sie einen großen (kiB -> MiB/GiB) dynamischen Speicherbereich wünschen, überprüfen Sie Ihre API für die Heap-Zuweisung. * "Variablen" * => nennen Sie es, was Sie wollen, nicht wichtig. – Ped7g

Antwort

3

Variablen sind ein High-Level-Konzept. Eine asm-Implementierung einer C-Funktion wird in der Regel eine Variable für einige Zeit in einem Register leben, aber vielleicht zu anderen Zeiten ist es in einem anderen Register leben, oder im Speicher an einem Ort, sobald es nicht mehr benötigt wird (oder Sie lief aus von Registern).

In asm haben Sie nicht wirklich Variablen (andere als statische Speicher), außer mit Kommentaren zu verfolgen, was was bedeutet. Verschieben Sie einfach Daten und erzeugen Sie ein aussagekräftiges Ergebnis.

Vermeiden Sie Speicher wann immer möglich. Sehen Sie sich die C-Compiler-Ausgabe an: Jeder vernünftige Compiler wird alles so gut wie möglich in den Registern behalten.

int foo(int a, int b) { 
    int c = a + 2*b; 
    int d = 2*a + b; 
    return c + d; 
} 

Diese Funktion stellt den folgenden 32-Bit-Code mit gcc6.2 -O3 -fverbose-asm (on the Godbolt compiler explorer). Beachten Sie, dass gcc Variablennamen an Register mit Kommentaren anhängt.

mov  ecx, DWORD PTR [esp+4] # a, a 
    mov  edx, DWORD PTR [esp+8] # b, b 
    lea  eax, [ecx+edx*2] # c, 
    lea  edx, [edx+ecx*2] # d, 
    add  eax, edx # tmp94, d 
    ret 
+0

Vielen Dank euch allen. Ich weiß es wirklich zu schätzen, dass ihr mir geholfen habt, damit ich das besser verstehen kann! –

1

Es scheint, als ob Sie MASM-Syntax verwenden. Der Standard MASM Ansatz lokale Variablen zu erstellen, ist

.CODE 
    PROC myProc 
    LOCAL a: DWORD 
    LOCAL b: DWORD 
    ; Initialize those vars 
    MOV a, 00000001 
    MOV b, 00001101 
    RET 
    ENDP myProc 

Die LOCAL Richtlinie schafft Platz auf dem Stapel für die Variablen EBP relative Indizierung.

+0

Ich denke, Sie sollten zumindest erwähnen, dass das Konzept der Hochsprachenvariablen auch auf Register abbilden kann, da es viel besser ist, das Verschütten auf den Stack zu vermeiden. –