[Watcom C] Inlineassembler und Pragmas

Rossibaer

Lieutenant
Registriert
Apr. 2007
Beiträge
754
Hallo zusammen,

nach längerer Pause würde ich mal wieder Deine Hilfe benötigen. Es geht um folgendes:

Ich habe mir die Open Source Quellcodes des Spiels Descent aus dem Netz geladen und bin nun eifrig am lesen und experimentieren damit. Der Quellcode wurde unter Verwendung von Watcom C und dem Macroassembler von Microsoft erstellt. Nun sehe ich immer wieder in für mich sehr reizvollen Bereichen des Quellcodes die Anwendung Pragma mit Inlineassembler, d.h. es werden ganz normal C Funktionen deklariert, aber dann mit Assemblerinstruktionen implementiert. Ein Beispiel:

Code:
1. Zeile:  vms_vector *vm_vec_make(vms_vector *v,fix x,fix y,fix z);
2. Zeile:  #pragma aux vm_vec_make "*_" parm [eax] [edx] [ebx] [ecx] value [eax] modify exact [] = \
3. Zeile:  "mov 0[eax],edx"	\
4. Zeile:  "mov 4[eax],ebx"	\
5. Zeile:  "mov 8[eax],ecx";

Was nun die einzelnen "movs" bedeuten ist für mich zweitrangig und auch nicht das Problem. Mir geht es hier um die #pragma Zeile und was sie genau im Detail bedeutet.

Folgendes vermute ich bereits erkennen zu können:
1. Zeile: den Funktionsprototypen definieren

2. Zeile: Pragma würde ich jetzt vermuten das der darauffolgende Assemblercode anstelle der Funktionsaufrufe im restlichen Quellcode hinein kompiliert/inlined wird, wobei jeder Aufruf von vm_vec_make mit beliebigem Suffix berücksichtigt wird, z.B.

Code:
vms_vector vec1 = vm_vec_make(v,x,y,z);

vms_vector vec2 = vm_vec_make2(v,x,y,z);

vms_vector vec3 = vm_vec_make3(v,x,y,z);

vms_vector vecFooBar = vm_vec_makeFooBar(v,x,y,z);

2. Zeile: Die Parameter v,x,y,z werden in die genannten Register verteilt ( ... param [eax] [edx] [ebx] und [ecx] ...), sodaß v => [eax], x => [edx], y => [ebx] und z => [ecx] ?

2. Zeile: "modify exact []" Heißt das es handelt sich um Referenzen, d.h. Änderungen werden auch an den Aufrufer wieder zurückgegeben? Oder heißt das nur das die Parameter als Wert übergeben werden und keine Veränderung stattfindet?

2. Zeile: "value [eax]" Ist der Rückgabewert der Funktion.

3. - 5. Zeile: die eigentlichen Assembleranweisungen, wobei zuerst das Ziel und als 2. Parameter die Quelle angegeben wird.

Wenn ich das so ähnlich in C schreiben möchte, dann wohl so:
(Die Typendefinitionen habe ich dabei aus den entsprechenden Headern herauskopiert.)

Code:
typedef long fix;
typedef struct vms_vector {
	fix x,y,z;
} vms_vector;
vms_vector * vm_vec_make(vms_vector *v,fix x,fix y,fix z)
{
   v.x = x;
   v.y = y;
   v.z = z;
}
[CODE]

Noch einmal kurz zusammengefaßt die Fragen:

Ist meine Interpretation des Pragmas soweit richtig?
Gibt es etwas, was ich dabei übersehen haben könnte?
Stimmt die Aussage, dass alle Funktionsaufrufe einschließlich derer mit einem Suffix im Namen durch den Assemblercode ersetzt werden?

Vielen Dank schonmal für das Interesse und das du dir die Mühe gemacht hast um das Ganze hier bis zum Ende zu lesen. Über eine Antwort würde ich mich freuen.

Viele Grüße
und happy coding...

Rossibaer :)

PS: Das ganze will ich in Visual C/C++ portieren, aber bis dahin will ich erstmal verstehen was da abläuft...

[B]EDIT[/B] Rückgabewert ergänzt
 
Zuletzt bearbeitet:
Ich denke es wird noch ein _ an den Symbolnamen angehaengt.
Evtl mit nem kleinen Beispiel mit dem Openwatcom Compiler testen?
 
Danke für deine Antwort, mit dem Symbolnamen würde ich das dann also so interpretieren, dass alle Aufrufe von "vm_vec_make" und "vm_vec_make_" ersetzt werden?

Zum OpenWatcom Compiler: Das habe ich mir auch erst überlegt, aber leider kann und möchte ich mir erstmal nicht den OpenWatcom Compiler dafür draufziehen, da ich vermutlich gänzlich überfordert wäre. Ich würde ungern noch einen weiteren Compiler/Interpreter oder sonstwas neben den anderen drauf schmeißen. Irgendwann wirds mir einfach zuviel und ich verliere gänzlich den Überblick und nutze das dann auch nur für den einen Augenblick... Das was ich hier geschrieben hatte, habe ich mir aus den Dokus zu Watcom C und meinen Fingern gelutscht und wollte halt mal hier nur anklopfen, ob einer das mal genauer beleuchten kann.
 
Vielleicht beantwortet das hier deine Frage? :)
 
Danke NullPointer, das was du verlinkt hast ist, recht informativ. Aber ich war auch nicht untätig in der Zwischenzeit und denke, dass ich nun den Sinn des speziellen Pragmas für InlineAssembler verstehe. Kurzum ich bin dazu übergegangen, die einzelnen Pragmas in C umzusetzen ohne dabei auf Performance o.ä. zu achten. Das war sowieso mein Ziel, da ich eine Version haben möchte, die nur noch aus C Code besteht und in VC kompilierbar ist, um diese dann weiter zu beackern.

Also danke nochmal
Rossibaer :)
 
Zurück
Oben