Inline Assembler in C
-
Hallo zusammen,
ich beschäftige mich gerade mit Inline Assembler in C und bin dabei auf ein komisches Phänomen gestoßen. Seht euch bitte mal diesen Code an:
#include <stdio.h> #include <stdlib.h> int main(void) { int a, b; int inv[4] = {1,2,3,4}; asm( // "pushl $0;" "movups (%%esi), %%xmm0;" //inv in SSE Register xmm0 laden "addps %%xmm0, %%xmm0;" //Jede Zahl mit sich selbst addieren "movups %%xmm0, (%%esi);" //Ergebnis wieder in inv schreiben : :"S" (inv) //inv in %esi laden :"%esi" ); for(int i = 0; i < 4; i++) { printf("%d\n", inv[i]); } return EXIT_SUCCESS; }
Das Programm macht genau das, was es tun soll: Es gibt Folgendes aus:
2
4
6
8Nun habe ich zwei Fragen:
1.) Das %esi Register ist 32 Bit groß. Wie kann dort aber ein ganzes Array, nämlich inv, passen? Warum funktioniert das?
2.) Wenn ich die auskommentierte Zeile mitausführe, so wird folgendes ausgeben:
-1219730907
4
6
8Die erste Zahl wird also durch Speichermüll ersetzt? Aber warum? Ich lege die Anfangsadresse des Arrays "inv" doch nur auf den Stack und ändere nichts am %esi-Register. Woher kommt diese Änderung?
Vielen Dank
LG, freakC++PS.: Falls dieser Thread doch ins Assembler-Forum soll, dann verschiebt ihn bitte dorthin.
-
- In esi steht die Adresse von inv.
- Keine Ahnung. Lass dich in Assembler-Forum verschieben, das hat mit C nichts zu tun.
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum Assembler verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
1.) Das bedeutet, dass ein Offset, beispielsweise 4(%esi) nur bedeutet, dass ich auf die Adresse des Arrays 4 addiere? Ok, das leuchtet mir ein.
2.) Hier suche ich noch eine Antwort
Vielen Dank
LG, freakC++
-
freakC++ schrieb:
2.) Hier suche ich noch eine Antwort
1. Auf jedes PUSH muss auch ein POP folgen.
2. GCC bekommt von der Veränderung des Stacks nichts mit und belegt ihn für printf nach dem Vor-ASM-Stand.Edit: 3. Du legst die Konstante 0 auf den Stack und nicht [inv].
viele grüße
ralph
-
Ahh :). Vielen Dank. Das leuchtet mir ein.
Ich habe noch eine andere Frage:
Warum wird hier in das komplette Array 0 geschrieben?
int arr[4] = {1,2,3,4}; asm( "movups (%%esi), %%xmm0;" "mulps %%xmm0, %%xmm0;" //Ohne diese Zeile wird 1 2 3 4 ausgegeben. Mit dieser Zeile jedoch 0 0 0 0 "movups %%xmm0, (%%esi);" : :"S"(arr) ); for(int i=0; i<4; i++) printf("%d ", arr[i]);
Ich verstehe nicht, warum hier 0 0 0 0 ausgegeben wird. Der mulps Befehl müsste doch 1*1 2*2 3*3 4*4, also 1 4 9 16 bewirken!?
Vielen Dank
LG, freakC++
-
freakC++ schrieb:
int arr[4] = {1,2,3,4}; ... "mulps %%xmm0, %%xmm0;" //Ohne diese Zeile wird 1 2 3 4 ausgegeben. Mit dieser Zeile jedoch 0 0 0 0 printf("%d ", arr[i]);
Ich verstehe nicht, warum hier 0 0 0 0 ausgegeben wird. Der mulps Befehl müsste doch 1*1 2*2 3*3 4*4, also 1 4 9 16 bewirken!?
MULPS verarbeitet Floats. Ändere mal das Int-Array in ein Float-Array und den Formatstring bei printf gleich mit.
viele grüße
ralph
-
Ohh! Super, du hast mir sehr geholfen. Jetzt funktioniert. Kennst Du denn einen Befehl, wie ich ints in floats umwandeln kann? Es wäre ja doof, wenn ich nur float-Arrays benutzen könnte.
Vielen Dank für die Hilfe
LG, freakC++
-
freakC++ schrieb:
Kennst Du denn einen Befehl, wie ich ints in floats umwandeln kann? Es wäre ja doof, wenn ich nur float-Arrays benutzen könnte.
Ich bin auch nicht sooo der SSE-Crack. So funktionierts schon mal:
#include <stdio.h> int main ( void ) { float arr[4] = {1,2,3,4}; int irr[4] = {1,2,3,4}; asm ( "movups (%%esi), %%xmm0\n" "mulps %%xmm0, %%xmm0;" "movups %%xmm0, (%%esi)\n" "movdqu (%%edi), %%xmm0\n" "cvtdq2ps %%xmm0, %%xmm0;" // 4 Integer zu 4 Single Floats "mulps %%xmm0, %%xmm0;" "cvttps2dq %%xmm0, %%xmm0;" // 4 Single Floats zu 4 Integer "movdqu %%xmm0, (%%edi)\n" : : "S" (arr), "D" (irr) // %%esi = [arr], %%edi = [irr] ); puts ("float:"); for (int i = 0; i < 4; i++) printf("%f\n", arr[i]); puts ("\ninteger:"); for (int i = 0; i < 4; i++) printf("%i\n", irr[i]); return 0; }
viele grüße
ralph
-
Ich werds ausprobieren. Danke für deine Mühe!
LG, freakC++