Speicherzugriffsfehler in Assembler?

3 Antworten

push[rbx] # push n-1

Ich könnte mir vorstellen, dass das hier das Problem ist, du pushst ständig etwas in den Stack, könnte sein, dass er irgendwann überläuft.

Wo genau definierst du den Stack?


Tischtennisftw 
Fragesteller
 16.11.2018, 16:27

Naja also ich definiere in eigentlich nicht. Ist das nicht einfach der normale Speicher auf den halt gepusht wird. Deswegen ja auch immer der Stackframe um die Funktion immer wieder aufrufen zu können

0
Ahzmandius  16.11.2018, 16:38
@Tischtennisftw

In unserem Modul MRT (Mikrorechnertechnik) haben wir immer einen Stack-Segment definieren müssen, wo wir auch sagen mussten wie groß der ist (ich weiß nicht mehr genau wie die Syntax war):

.stack 16

16 stand dann für die Größe des Stacks. 16 Byte z.B.

Was mein anderen Einwand angeht ist das so gemeint:

Sagen wir das n=3, dann wird dein Stack vor dem nächsten Call doch so aussehen (bzw. er wäre von obennach unten angeordnet denke ich, ist aber unergeblich):

{bsp1 <- stack pointer

ret1

3}

nach dem zweiten call und kurz vor dem 2 call sehe der Stack dann doch so aus:

{(bsp2) <- stack pointer

ret2

2

bsp

ret1

3}

usw.

Dann wäre der Stack doch irgendwann voll bei hinreichend großem n, oder nicht?

0
KarlRanseierIII  16.11.2018, 17:15
@Ahzmandius

Ja sicherlich, aber sein n ist bei 10, sodaß insgesamt c.a. 2^10 Stackframes angelegt werden sollten. selbst wenn ich großzügig mit 64 Bytes rechne, sind das gerade 64KB. Der normale Stackframe bei Linux sollte bei 8 MB liegen und auch bei Windows ist er 1(?)MB, wenn ich es recht im Kopf habe.

Wenn also kein extrem grober Unfug bei der Stackverwaltung passiert, dann sollte die Tiefe nicht das Problem sein, denn:

Im Normallfall wird erst ein Pfad bis zum Blatt der Rekusion abgelaufen, die Stacktiefe sollte also bei c*n liegen, da ist also einiges an Luft.

1

Frage, was sagt gdb denn dazu, wo genau der Zugriffsfehler stattfindet? Vielleicht hilft Dir das bei der Analyse.

push [n] # parameter: fibonacci number to calculate
call f # call function
add rsp, 8 # remove parameter from stack

Wäre es nicht sauberer zu pop-en? Auch wenn es konkret ein grow-down stack ist.


Tischtennisftw 
Fragesteller
 16.11.2018, 16:26

Ja das vorgegeben mit dem add rsp, 8. Mit gdb krieg ich das gerade nicht hin, aber trotzdem danke :)

0

Nach den internen Calls auf f fehlt der ADD RSP,8

Man kommt bei Assembler einfacher mit Pascal- oder stdcall Aufrufkonvention klar: Die Return-Anweisung enthält die Anzahl der Bytes, die vom Stack freigegeben werden.

Außerdem sicherst Du in f nicht den Inhalt von RBX