GCC Inline-Assembler
-
Ich suche ein gutes und einfaches Tutorial zu Inlines Assembler für x86-Architekturen mit dem GCC.
Mit dem:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
komme ich noch nicht ganz zurecht.
Eine Stufe ausführlicher wäre nicht schlecht.
-
Wie wäre es mit Dokumentation des Compilers?
-
Ich verushce mich grad reinzuarbeiten.
GCC-Seite war gestern noch down.
Kann mir jmd diesen Intel-Style-Code in At&T übersetzen bitte?
__asm { MOV EAX Op_A // Load pointers into CPU regs MOV EBX, Op_B MOVUPS XMM0, [EAX] // Move unaligned vectors to SSE regs MOVUPS XMM1, [EBX] ADDPS XMM0, XMM1 // Add vector elements MOVUPS [Ret_Vector], XMM0 // Save the return vector }
-
Wenn es um SSE geht, kannst du auch die Compiler intrinsics benutzen. Sie sind besser portierbar als inline Assembler.
-
Der Lesbarkeit wegen, würde ich an deiner Stelle beim Intel Syntax bleiben (den GGC ebenfalls kennt).
-
Zum Umwandeln der Syntax einfach Argumente vertauschen und ggf. Syntax der Memoryreferenzen etc. anpassen, wie auf http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm beschrieben.
-
Ich habe mittlerweile ein funktionierendes Beispiel für die Verwendung von SSE mittels Inline- Assembler gefunden.
Da ich mit Assembler bisher wenig Kontakt hatte, möchte ich dennoch darum bitten, dass mir jemand erklärt was in den einzelnen Schritten passiert
float *a, *b; // und initialisierung __asm__ __volatile__ ( "movups (%0), %%xmm0\n\t" "mulps (%1), %%xmm0\n\t" "movups %%xmm0, (%1)" : : "r" (a), "r" (b) );
Ich fange mal von vorne = unten an.
: "r" (a), "r" (b)
Wenn ich es richtig verstehe, sind das die Input-Operanden, die ich in Allzweckregistern speichern möchte.
Nun: was sind diese Allzweckregister in dem Fall? rax oder eax? Also verwendet mein 6-Bit System die 64-bit oder 128-Bit Register?
Und was steht dann genau in den Allzweckregistern?
Steht dort dann a[0], was ich glaube, oder doch die Adresse des Arrays, also a?"movups (%0), %%xmm0\n\t"
Hier werden 4 nicht alignte floats nach xmm0 geladen. Ich nehme an, dass
(%0) eine Dereferenzierung ist, da ich vermute dass in %0 a[0] steht."mulps (%1), %%xmm0\n\t"
Hier findet die Multiplikation statt.
Nun frage ich mich, wieso nur a in ein SSE-Register geladen werden musste.
Ich hab mal in der Doku geblättert:0F 59 /r - MULPS xmm1, xmm2/m128
Multiply packed single-precision floating-point values in xmm2/mem by xmm1.The source operand can be an XMM register or a 128-bit memory location.
Ich nehme an, dass die 128-bit Adresse verwendet wird.
Wieso funktioniert das? Muss das zweite Array in dem Fall am Stück im Speicher liegen? Muss es in irgendeiner Form angeordnet sein?"movups %%xmm0, (%1)"
Ich denke, wenn das obige klar ist, wird diese Zeile trivial.
Ich hoffe, dass sich jemand die Zeit nimmt, mal den COde und meine Gedanken dazu durchzugehen und mir ein Feedback zu geben.
-
Ich bin das ganze nochmal durchgegangen.
Ich denke einige Punkte sind klarer geworden, andere hingegen nicht.
Ich glaube, dass a[0] nirgendwo vorkommt.
Ich speichere ja die Adresse auf die der Zeiger a zeigt in ein Register.
Und die Klammern sollen ja nur bedeuten, dass der Wert in dem register dann als Adresse zu interpretieren ist.Wenn ich das Assembly anschaue, erübrigt sich auch die Frage nach den verwendeten Registern. Bei mir werden rax und rdx verwendet. Nur wieso eigentlich?
Immer noch nicht klar ist der Memory-Teil von mulps.
-
Hat jemand Beispielcode zu FMA-Operationen im Gcc?
Ich bräuchte es dringend.Nach einer Matrix-Addition soll nun Multiplikation mit anschließender Addition gemacht werden.
Und das ganze ohne die dazugehörige Hardware. Überfordert mich irgendwie