Assembler: Fehlerhafter Stackframe

Pascal, Basic und andere nicht aufgelistete
Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Re: Assembler: Fehlerhafter Stackframe

Beitrag von Architekt » Mo Jun 16, 2014 10:28 am

Nur pro forma ob ich überhaupt verstanden habe, was da vorgeht, hier einmal von mir kommentierter Assembler. Sind meine Kommentare zutreffend?

Code: Alles auswählen

.text
.globl _prog

_prog:
push	%ebp
movl	%esp, %ebp

subl	$8, %esp # Speicher anfordern für 2 Variablen

movl	$4, (%esp) # a = 4
movl	$8, 4(%esp) # b = 8

movl	(%esp), %eax # %eax = a = 4
push	%eax # push a = 4
movl	4(%esp), %eax # %eax = b = 8
imull	8(%esp), %eax # 4 * 8 = 32
addl	$4, %esp

push	%eax # push 32
call	_println_int
addl	$4, %esp

movl	4(%esp), %eax # %eax = b = 8
push	%eax # push b = 8
movl	(%esp), %eax # %eax = a = 4
imull	8(%esp), %eax # 8 * 4 = 32
addl	$4, %esp

push	%eax # push 32
call	_println_int
addl	$4, %esp

addl	$8, %esp # Speicher freigeben

pop 	%ebp
ret

Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Re: Assembler: Fehlerhafter Stackframe

Beitrag von Architekt » Mo Jun 16, 2014 12:22 pm

Ich bin gerade glaube ich auf die Idee gekommen, würde aber gerne wissen, ob ich richtig liege und wenn, warum das so ist.

Nehmen wir an:

Code: Alles auswählen

movl $4, (%esp)
movl $8, 4(%esp)
Wenn ich nun multipliziere, ist mir aufgefallen, dass ich den zuletzt benutzen offset + 4 brauche, um imull richtig zu benutzen. In Assembler:

Code: Alles auswählen

movl (%esp), %eax # ist ja gleichbedeutend mit Offset 0
imull 4(%esp), %eax # Offset: 4 = 0 + 4
und

Code: Alles auswählen

movl 4(%esp), %eax # Offset = 4
imull 8(%esp), %eax # Offset: 4 + 4 = 8
Wäre nett, wenn du mir sagst, ob ich richtig liege. :)

nufan
Wiki-Moderator
Beiträge: 2448
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Assembler: Fehlerhafter Stackframe

Beitrag von nufan » Mo Jun 16, 2014 4:49 pm

Architekt hat geschrieben:In dem Tutorial, auf das ich mich stütze, macht er das so, dass er für Variablen negative Offsets benutzt:
http://magazin.c-plusplus.de/artikel/Compilerbau
Speziell hier in seinem VarManager: http://www.c-plusplus.de/magazin/bilder ... r_man1.cpp

Ist das die Rätsels Lösung?
Das ist im Prinzip genau das was ich vorgeschlagen hab ^^ Eine ganz primitive High-Level-Speicherverwaltung in der du Variablennamen einem Stack-Offset zuordnest.
Architekt hat geschrieben:Nur pro forma ob ich überhaupt verstanden habe, was da vorgeht, hier einmal von mir kommentierter Assembler. Sind meine Kommentare zutreffend?

Code: Alles auswählen

.text
.globl _prog

_prog:
push	%ebp
movl	%esp, %ebp

subl	$8, %esp # Speicher anfordern für 2 Variablen

movl	$4, (%esp) # a = 4
movl	$8, 4(%esp) # b = 8

movl	(%esp), %eax # %eax = a = 4
push	%eax # push a = 4
## push verändert dein %esp! offset 4 stimmt für b nicht, es müssten 8 sein.
## Du schreibst hier a in dein Register.
movl	4(%esp), %eax # %eax = b = 8
imull	8(%esp), %eax # 4 * 8 = 32
## a wird wieder vom Stack genommen
addl	$4, %esp

push	%eax # push 32
call	_println_int
addl	$4, %esp

movl	4(%esp), %eax # %eax = b = 8
push	%eax # push b = 8
## Du hast gerade 8 gepushed, also liegt das auch ganz oben am Stack und nicht 4.
movl	(%esp), %eax # %eax = a = 4
imull	8(%esp), %eax # 8 * 4 = 32
addl	$4, %esp

push	%eax # push 32
call	_println_int
addl	$4, %esp

addl	$8, %esp # Speicher freigeben

pop 	%ebp
ret
Da sind doch ein paar kleinere Fehler drin, ich hab mal mit Doppel-Raute ein paar Kommentare eingefügt. Vergiss nicht, dass push dein %esp verändert und du das bei allen folgenden Offsets mitrechnen musst! Alternative wäre es lokale Variablen über dein konstantes %ebp mit negativen Indizes zu referenzieren, dann hast du immer den selben Ausgangspunkt.
Architekt hat geschrieben:Wäre nett, wenn du mir sagst, ob ich richtig liege. :)
Bitte sag mir genau was dein Code machen soll. Klar, mit Offset 0 und Offset 4 bekommst du die zwei obersten Variablen am Stack. Aber ich bin mir nicht sicher, was du erreichen willst.


Ich hab bis morgen Abend noch einiges zu erledigen. Bitte nicht persönlich nehmen wenn ich bis dahin nicht antworte.

Antworten