func bar(p: int): int var l: int; l := foo(p); return l + p; end func foo(p: int): int return bazz() + quux(); end func bazz(): int return 3; end func quux(): int return 2 * bazz(); end
/- | ... | | | Lokale Variable 2 | | | Lokale Variable 1 | | | Callee-Save-Register | Aktivierungsrahmen | | Framepointer | -> ab hier kümmert sich die aufgerufene Funktion der aufgerufenen < | Rücksprungaddresse | -> das kommt durch die Call Instruktion Funktion | | Argument 1 | -> bis hier kümmert sich die aufrufende Funktion | | Argument 2 | | | ... | | | Argument n | \_ | Caller-Save-Register | |----------------------| Aktivierungsrahmen /- | ... | der aufrufenden < | ... | Funktion \_ | ... | | ... |
func foo(p: int): int func bar(q: int): int func bazz(): int return p * 2; end return bazz() + 2; end func quux(): int return bar(42) + 69; end return quux() + bar(); end
quux
bar
auf, aber die umschließende Funktion von bar
ist foo
.class Widget var i: int; end class Button : Widget var text: String; func foo(): int return i * 2; end end func main(): int var w: Widget; w := new Button(); w.foo(); end
int 3
Befehl, ist extra nur ein Byte lang, löst eine Trap aus, die das Betriebssystem dem Debugger zustelltint 3
kann der Debugger Speicher und Register lesen/schreiben.a
in Ausdruck öfter vor, also gibt es mehrere Kanten zu a.Name | Instruktion | Kosten |
---|---|---|
L | $r_i = M_x$ | 2 |
S | $M_x = r_i$ | 2 |
RoR | $r_i = r_i \circ r_j$ | 2 |
RoM | $r_i = r_i \circ M_x$ | 2 |
Zeit um.
Danach selbstverständlich noch die Frage, was ich mir selbst geben würde, hab das etwas begründet, gesagt das ich eigentlich alles wusste, mich nicht aufs Glatteis führen habe lassen, nur bei undefiniertem/unspezifiziertem Verhalten mich verhört habe. Meine Debugger Erklärung waren nicht ganz sauber, aber richtig und gut.