Entwickler-Ecke

Algorithmen, Optimierung und Assembler - assembler variable benutzen


uall@ogc - Mi 16.02.05 14:55
Titel: assembler variable benutzen
ich hatte mal wieder nen bischen zeit da hab ich mal folgendes getestet:

wenn man in eine globale variabel was schreibt
user defined image
wenn man eine globale variable ausließt
user defined image

beides mal wird [variablenname] benutzt (so zeigt der debugger von delphi es an)
jetzt habe ich mal eine funktion geschrieben mit stdcall;

auslesen funktioniert mit [] und ohne []
user defined image
user defined image

schreiben funktioniert auch mit [] und ohne []
user defined image
user defined image

so und nun was mich bisl nervt
hat man eine funktion ohne stdcall (wie normalerweise in delphi)
kappt das auslesen von der variable ohne [] einwandfrei (eax ist ja die variable)
user defined image

jedoch checkt delphi es mit [] nicht das man den wert der variable haben will:
user defined image

denk mal das sollte normal auch anders sein (also mov ebx, [b] sollte mov ebx, eax liefern, delphi erkennt es aber nicht)

danke für die die es sich durchgelesen haben ;>

Moderiert von user profile iconAXMD: Img-Tags repariert; bitte nächstes Mal HTTP davor ;)


tommie-lie - Mi 16.02.05 15:04
Titel: Re: assembler variable benutzen
Was ist jetzt die Frage, oder was verstehst du daran nicht?
Bei stdcall sind die Variablen nunmal auf dem Stack, bei register sind sie in den Registern. Pointer auf den Stack musst du derefernezieren ([]), Rohdaten in Registern nicht.

Tho-dasproblemnichtsehend-mas


uall@ogc - Mi 16.02.05 15:17

meine frage ist warum delphi zu dumm ist und bei einer funktion (ohne stdcall)

aus


Delphi-Quelltext
1:
mov ebx, [b]                    

ein

Delphi-Quelltext
1:
mov ebx, [eax]                    


macht. das doch nen bug oder hats einen tieferen sinn?


tommie-lie - Mi 16.02.05 15:42

uall@ogc hat folgendes geschrieben:
meine frage ist warum delphi zu dumm ist und bei einer funktion (ohne stdcall) ausmov ebx, [b]ein mov ebx, [eax]macht. das doch nen bug oder hats einen tieferen sinn?
Was ist denn b? Ein Parameter der Funktion? Dann ist es kein Bug, denn du willst auf [b] zugreifen (ein Zugriff auf die Speicheradresse, auf die b zeigt, b wird als Pointer gehandhabt (Pointer(b)^)). b steht aber wegen register Calling Convention in EAX, also wird ein [EAX] draus. Wenn es eine lokale Variable ist, ist es sowieso wahrscheinlich, daß die Variable in einem Register landet und nicht auf dem Stack.
Bei globalen Variablen sind die Variablen offensichtlich Symbole, die deshalb im Klartext (ohne Stack- oder Register-Referenz) im Assemblercode auftauchen, die werden halt später vom Linker ersetzt.


en!gma - Mi 16.02.05 15:44

ich glaub b soll einfach eine variable sein...integer geh ich mal von aus wenn er ganz oben b:=1 gesetzt hat


uall@ogc - Mi 16.02.05 15:50

wenn du dir bild 3 und 4 anguckst siehste das delphi das dort erkennt und beides mal ds selbe raus macht....

thoeretisch ist der aufruf von


Delphi-Quelltext
1:
mov ebx, [b]                    



wobei b ein integer ist richtig, da ich den inhalt von b in ebx schreiben will - bei globalen variablen funktioniert es ja aber bei lokalen halt nicht (auch nur in einer funktion wenn b der parameter ist)

ob ich nu


Delphi-Quelltext
1:
mov ebx, b                    


oder


Delphi-Quelltext
1:
mov ebx [b]                    


mache ist in ALLEN anderen fällen egal, delphi erkennt das selbstständig nur wenn es sich um einen parameter handelt rafft delphi es nicht das es aus


Delphi-Quelltext
1:
mov ebx, [b]                    


halt trotzdem ein


Delphi-Quelltext
1:
mov ebx, eax                    


macht (ansonsten unterscheidet delphi das schon und machst immer richtig, nur da halt nicht)
deshalb würde ich es halt als BUG bezeichnen...


tommie-lie - Mi 16.02.05 15:50

en!gma hat folgendes geschrieben:
ich glaub b soll einfach eine variable sein...integer geh ich mal von aus wenn er ganz oben b:=1 gesetzt hat
Welcher Typ es ist, sehe ich auch, und daß er für so einen Test einen einfachen Integer nimmt, ist mir auch klar, wenn er die 32-bit-Register benutzt ;-)
Ich meinte die Art der Variable, nicht den Datentyp.


en!gma - Mi 16.02.05 15:53

aso sry halt mich raus wenn ich keine ahnung hab ;D


tommie-lie - Mi 16.02.05 16:24

uall@ogc hat folgendes geschrieben:
wenn du dir bild 3 und 4 anguckst siehste das delphi das dort erkennt und beides mal ds selbe raus macht....
Ja, weil b ein globales Symbol ist, und klar ist, daß du den Wert haben willst.

uall@ogc hat folgendes geschrieben:
wenn es sich um einen parameter handelt rafft delphi es nicht das es aus mov ebx, [b]halt trotzdem einmov ebx, eaxmacht
Das sieht bei dir aber anders aus:
user defined image
Aus "mov reg, [a]" wurde offensichtlich auch ein "mov reg, [reg]" und nicht ein "mov reg, reg". Alles richtig, denn der Wert befindet sich effektiv in eax, und wenn der Programmierer so blöd ist un den Integer dereferenziert, ist er für die AV selbst verantwortlich ;-)
Variablen, die irgendwo im Speicher sind (also auf dem Stack, im Modul oder weiß der Geier wo) müssen so oder so dereferenziert werden. Ein "mov eax, [param1]" (cc: stdcall) müsste zunächst param1 dereferenzieren. "mov eax, [[param1]]" ist aber syntaktisch (und technisch) nicht möglich, daher wird es nur einmal dereferenziert.
Der einzige Fehler, den ich hier sehe, ist, daß er bei "[param1]" nicht meckert, weil er eigentlich zweimal dereferenzieren müsste, dies aber nicht kann. Abgesehen davon verhält sich Delphi hier aber richtig, schließlich sollte der Programmierer, wenn er seinen Code in Assembler schreibt, schon wissen, was er da tut. Das beinhaltet auch, daß er weiß, wo und in welcher Form seine Variablen liegen.


uall@ogc - Mi 16.02.05 16:36

das ist ja auch soweit richtig
aber warum macht delphi hier einen unterschied zwischen


Delphi-Quelltext
1:
2:
mov, edx [b] und
mov edx, b


wenn man sonst in allen fällen ja immer den wert von b in edx schreibt
d.h. warum interpretiert delphi [b] dort auf einmal als wenn ich den wert an der adresse haben will
nur weils bei globalen variablen nicht funktioniert wegen doppelten [[]]?
dann dürfe mir delphi aber auch nicht bei

a := 1; (global)
ein

Delphi-Quelltext
1:
mov [a], 1                    

im debugger draus machen

delphi sollte DANN IMMER

Delphi-Quelltext
1:
mov eax, b                    

benutzen auch im eigenen debugger (siehe bild1, 2)

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt.


tommie-lie - Mi 16.02.05 16:48

uall@ogc hat folgendes geschrieben:
aber warum macht delphi hier einen unterschied zwischen

Delphi-Quelltext
1:
2:
mov, edx [b] und
mov edx, b
Weil es in diesem Fall möglich ist, weil es eben nur ein Register ist und kein Speicherbereich. Der Programmierer muss hier selbst drauf achten. Wie gesagt, was ich als Bug ansehe, ist, daß er keine Warnung oder ähnliches ausgibt, wenn er aus einem "mov eax, [b]" nur ein "mov eax, [addr]" macht, weil er nicht zweimal dereferenzieren kann, obwohl er es laut Syntax eigentlich müsste.

uall@goc hat folgendes geschrieben:
dann dürfe mir delphi aber auch nicht beia := 1; (global)einmov [a], 1im debugger draus machen, delphi sollte DANN IMMERmov eax, bbenutzen auch im eigenen debugger (siehe bild1, 2)
Schmarrn, das würde "@a := 1" entsprechen, weil ich den Wert 1 in die Variable a schreiben will und nicht das Symbol a umbiegen will. Das eine ist nunmal Pascal, das andere Assembler.