Seite 3 von 3
Re: Assembler: Fehlerhafter Stackframe
Verfasst: Mo Jun 16, 2014 10:28 am
von Architekt
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
Re: Assembler: Fehlerhafter Stackframe
Verfasst: Mo Jun 16, 2014 12:22 pm
von Architekt
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:
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.
Re: Assembler: Fehlerhafter Stackframe
Verfasst: Mo Jun 16, 2014 4:49 pm
von nufan
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.