Markus Wichmann
2006-09-18 18:18:01 UTC
Hi all,
ich wollte mal wissen, ob ich das mit der C-Aufrufskonvention (ich weis,
deutsch klingt es blöd) richtig verstanden habe. Also, zunächst pusht
der Rufer die Parameter falschrum auf den Stack. Dann ruft er die
Funktion, und danach löscht er den Stack wieder:
push letzter_param
push erster_param
call my_function
add esp,sizeof(params)
Die Funktion soll dann ebp sichern und eine Stackframe eröffnen (oder
welchen Genus 'frame' im deutschen auch immer hat):
my_function:
push ebp
mov ebp,esp
Meine Frage betrifft die lokalen Variablen. Was ich machen muss, ist
klar: Vom esp die Größe der Variablen in Byte abziehen:
sub esp,4
bzw. initialisierte Variablen pushen (wäre jedenfalls cleverer):
push dword 0
Aber wie greife ich auf diese Variablen jetzt zu? Mit [ebp-Stelle],
wobei ich das schon am Anfang per Präprozessor festlegen wollte. Ach ja,
bei NASM eignet sich welche Direktive besser? %assign oder %define? In
jedem Fall, wie kann ich jetzt z.B. den Inhalt des ersten Parameters
nach ax verschieben? (Unter der Annahme, es handele sich um einen
16-Bit-Wert). Von [ebp-0] bis [ebp-3] liegt ja der alte ebp. Also mit
mov ax,[ebp-4]
oder wie? Und jetzt noch was: Wenn ich Pointer übergeben kriege (als
Parameter), wie groß sind die unter WinNT (also Windows mit NT-Kernel =
NT + 2kx + XP + Vista (glaub)) Ich verwende momentan Windows 2000, aber
mein Programm soll ja auch portierbar sein.
Um es ganz konkret zu machen: Unter C heist die Anweisung
x0 = *in++;
Wie geht das unter Assembler, unter der Maßgabe, dass x0 die erste
lokale Variable und *in der erste Parameter ist (liegt also direkt auf
ebp). Falls das nötig sein sollte: Datentyp ist in beiden Fällen
unsigned int16. Nur das *in eben ein Pointer da drauf ist.
Mein momentaner Code lautet:
mov ax,[ebp+2]
mov [ebp-4],ax
inc ax
... ; hier wird noch viel mehr mit dem Wert gemacht, also lasse ich
; ihn gleich im Register und schreibe ihn erst danach zurück
mov [ebp+2],ax
Ich hab aber das gefühl, dass das nicht so ganz stimmt. Ich hab es noch
nicht ausprobiert (weil ich noch nicht fertig bin), aber stimmt meine
Befürchtung?
tia und cu,
nullplan
ich wollte mal wissen, ob ich das mit der C-Aufrufskonvention (ich weis,
deutsch klingt es blöd) richtig verstanden habe. Also, zunächst pusht
der Rufer die Parameter falschrum auf den Stack. Dann ruft er die
Funktion, und danach löscht er den Stack wieder:
push letzter_param
push erster_param
call my_function
add esp,sizeof(params)
Die Funktion soll dann ebp sichern und eine Stackframe eröffnen (oder
welchen Genus 'frame' im deutschen auch immer hat):
my_function:
push ebp
mov ebp,esp
Meine Frage betrifft die lokalen Variablen. Was ich machen muss, ist
klar: Vom esp die Größe der Variablen in Byte abziehen:
sub esp,4
bzw. initialisierte Variablen pushen (wäre jedenfalls cleverer):
push dword 0
Aber wie greife ich auf diese Variablen jetzt zu? Mit [ebp-Stelle],
wobei ich das schon am Anfang per Präprozessor festlegen wollte. Ach ja,
bei NASM eignet sich welche Direktive besser? %assign oder %define? In
jedem Fall, wie kann ich jetzt z.B. den Inhalt des ersten Parameters
nach ax verschieben? (Unter der Annahme, es handele sich um einen
16-Bit-Wert). Von [ebp-0] bis [ebp-3] liegt ja der alte ebp. Also mit
mov ax,[ebp-4]
oder wie? Und jetzt noch was: Wenn ich Pointer übergeben kriege (als
Parameter), wie groß sind die unter WinNT (also Windows mit NT-Kernel =
NT + 2kx + XP + Vista (glaub)) Ich verwende momentan Windows 2000, aber
mein Programm soll ja auch portierbar sein.
Um es ganz konkret zu machen: Unter C heist die Anweisung
x0 = *in++;
Wie geht das unter Assembler, unter der Maßgabe, dass x0 die erste
lokale Variable und *in der erste Parameter ist (liegt also direkt auf
ebp). Falls das nötig sein sollte: Datentyp ist in beiden Fällen
unsigned int16. Nur das *in eben ein Pointer da drauf ist.
Mein momentaner Code lautet:
mov ax,[ebp+2]
mov [ebp-4],ax
inc ax
... ; hier wird noch viel mehr mit dem Wert gemacht, also lasse ich
; ihn gleich im Register und schreibe ihn erst danach zurück
mov [ebp+2],ax
Ich hab aber das gefühl, dass das nicht so ganz stimmt. Ich hab es noch
nicht ausprobiert (weil ich noch nicht fertig bin), aber stimmt meine
Befürchtung?
tia und cu,
nullplan
--
To err is human. To forgive is divine.
To forget is also human...
To err is human. To forgive is divine.
To forget is also human...