Inline-Assembler

studypad
Endlosschleifenbastler
Endlosschleifenbastler
Beiträge: 158
Registriert: 30. Mär 2011 11:46

Inline-Assembler

Beitrag von studypad »

Wie weise ich denn Werte eines Arrays den Variablen im Inline-Assembler in einem C Programm zu

Angenommen:

Code: Alles auswählen

asm ("..."
"..."
"fld x1"
: "x1" (arr[1][2])
);
Oder wie sollte das funktionieren?

kai j
Erstie
Erstie
Beiträge: 20
Registriert: 2. Nov 2011 22:50

Re: Inline-Assembler

Beitrag von kai j »

[wie lösche ich einen Beitrag?]

hstr
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 128
Registriert: 14. Apr 2011 22:52

Re: Inline-Assembler

Beitrag von hstr »

Das würde ich auch gerne wissen.. :?

Benutzeravatar
Cpro
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 111
Registriert: 16. Okt 2010 22:13
Wohnort: Darmstadt

Re: Inline-Assembler

Beitrag von Cpro »

Ganz einfach: Wenden Sie sich mit einem handschriftlich verfassten Dokument, auf dem ihr Nutzername, Kennwort, Matrikelnummer und eine Begründung stehen, einer Kopie Ihres amtlichen Lichtbildausweises und einer Bearbeitungsgebühr von 7,50€ an das Studierendensekretariat, welches einen Stempel auf das Dokument macht, damit gehen Sie dann zum Präsidenten der TU und lassen sich das Dokument 9x kopieren, beglaubigen und entgegen zeichnen, damit gehen Sie dann ins D120 und übergeben das "Original" (wichtig) einer Person, die Sie dort antreffen. Die 9 Kopien müssen in einen Umschlag verschlossen werden und ausreichend frankiert an alle Mitgliedsuniversitäten der TU9 geschickt werden (auch postalisch nach Darmstadt!). Nach ca. 2-3 Wochen erhalten Sie von allen Universitäten eine Bestätigung, diese sammeln Sie und wenn Sie alle komplett vorliegen haben, reichen Sie diese im D120 ein, woraufhin ihr Beitrag gelöscht wird... simpel oder? :D

mw1039
Computerversteher
Computerversteher
Beiträge: 346
Registriert: 12. Apr 2011 12:18

Re: Inline-Assembler

Beitrag von mw1039 »

Die einfachste Moeglichkeit geht folgendermassen:
arr ist ja ein Pointer auf das nullte Element des Arrays. Im Inline-Assembler kann man eins der Register (z.B. esi) an diese Adresse binden:

Code: Alles auswählen

asm ("..."
"..."
"fld x1"
: "S" (arr), ...
: ...
);
Anschliessend kann man (indem man das zweidimensionale als eindimensionales Array behandelt) auf alle Elemente zugreifen. Z.B.

Code: Alles auswählen

asm ("fld (%%esi);" // <-- laed arr[0]
"addl $4, %%esi;"
"fld (%%esi);" // <-- laed arr[1]
"addl $16, %%esi;"
"fld (%%esi);" // <-- laed arr[5]
: "S" (arr), ...
: ...
);

hstr
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 128
Registriert: 14. Apr 2011 22:52

Re: Inline-Assembler

Beitrag von hstr »

Danke für die Antwort, ich musste nur noch eine kleine Änderung vornehmen,
die aber wahrscheinlich auf eine andere g++ Version als auf den Pool Rechnern zurückzuführen ist:
Statt "S" (arr) --> "S" (*arr)

der_apfel
Erstie
Erstie
Beiträge: 14
Registriert: 9. Apr 2010 22:47

Re: Inline-Assembler

Beitrag von der_apfel »

Ich hab auch eine Frage zum Inline Assembler.

Code: Alles auswählen

printf("Davor: %f %f, %f, %f\n", vek[0],vek[1], vek[2],vek[3]);
	float vek[4] = { 4.0, 3.0, 2.0, 1.0 };
	asm( "xorl %%eax, %%eax;"
			"movups (%%ecx), %%xmm0;"
			"addps %%xmm0, %%xmm0;"
			"movups %%xmm0, (%%ecx);"
			:
				"=c" (*vek)
			:
				"*c"(vek)
			:
				"xmm0",
				"eax"
			);
	printf("Danach: %f %f, %f, %f\n", vek[0],vek[1], vek[2],vek[3]);
Bei mir kommt statt dem erwarteten Ergebnis immer etwas "zufälliges" für vek[0] raus.
Der Rest von den anderen 3 Werten wird aber immer korrekt angezeigt.

Ich weiß nicht woran das liegen könnte.

ps: als zusätzliches Compilerflag war noch "-msse" gesetzt

simon.r
Mausschubser
Mausschubser
Beiträge: 59
Registriert: 4. Okt 2010 16:13

Re: Inline-Assembler

Beitrag von simon.r »

Wenn du deine Input-/Outputanweisungen betrachtest, dann sollte dich das nicht verwundern: Du lässt am Anfang die Adresse des ersten Elements von vek in ecx schreiben (wobei die Bedeutung von * mir unbekannt ist). Am Ende lässt du den Wert, der gerade in ecx steht, auf das erste Element von vek schreiben. Dh. vek[0] enthält nach dem asm Block die eigene Adresse! Sofern du die Ausgabeanweisung ["=c" (*vek)] entfernst, sollte es funktionieren.

der_apfel
Erstie
Erstie
Beiträge: 14
Registriert: 9. Apr 2010 22:47

Re: Inline-Assembler

Beitrag von der_apfel »

na ja als erstes hatte ich "=c" (vek) bei den Zuweisungen stehen, aber diesen Code hab ich nicht kompiliert gekriegt.
Nur wenn ich das wie oben geschrieben hab ich den Code kompiliert gekriegt.
Wenn man aber einen separaten Pointer float* p1 = vek, definiert hatte, dann funktionierte die Zuweisung am Ende mit "=c" (p1) und die eingabe mit "*c" (p1).

btw: Der Grund warum ich diese Zuweisung dort stehen haben wollte ist, dass mMn die Lesbarkeit erhöht wird, nämlich dass der Wert von vek in dem Block verändert wurde.

Benutzeravatar
Ronny
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 133
Registriert: 18. Nov 2005 14:33
Wohnort: IGD

Re: Inline-Assembler

Beitrag von Ronny »

Die Variable vek selbst ist nur scheinbar vom Typ "int *".
So funktioniert die Zuweisung:

Code: Alles auswählen

float * p = vek;
Andersherum kann man folgendes nicht machen:

Code: Alles auswählen

float vek[4] = { 4.0, 3.0, 2.0, 1.0 };
float * p = ...;
vek = p; // Funktioniert nicht
Das Problem ist, dass das vek Array auf dem Stack abgelegt wird, da seine Groesse schon zur Compilezeit bekannt ist.
Der Compiler weis genau wo das Array im Stack relativ zu ebp beginnt.
Deswegen funkioniert auch die Zuweisung "float * p = vek;".

vek selbst ist keine wirkliche Pointervariable die veraendert werden kann.
Das ist auch der Grund, warum "=c" (vek) nicht vom Compiler angenommen wird, da der Wert von ecx nicht in vek geschrieben werden kann.
"=c"(p) funktioniert aber, da p eine echte Pointervariable ist (veraendert aber nur die Adresse, die in p gespeichert ist).
Was das * bei "*c"(p1) bedeutet ist mir unklar.
Es geht eigentlich auch ohne *.

Des Weiteren stimmt was simon.r bezueglich der zufaelligen Werte gesagt hat.

majias
Neuling
Neuling
Beiträge: 7
Registriert: 9. Nov 2011 22:34

Re: Inline-Assembler

Beitrag von majias »

Wir haben jetzt die Teilaufgabe a) ohne SSE gelöst aber jetzt haben wir Probleme bei der b).
Wir verstehen die Zuweisungen am Ende nicht.
Muss man die Matrix und den Vektor als Input und den Ergebnisvektor als Output zuweisen?
Wie das dann mit Arrays gehen würde haben wir auch noch nicht verstanden. Wir hatten bisher ja nur Beispiele mit einfachen Zahlen.
Muss man den Code aus der 1a) eigentlich noch stark verändern für die 1b) oder kann man ihn mehr oder weniger mit copy & paste übernehmen?

Hoffe ihr könnt uns helfen, wir sind grad ein bisschen verwirrt :?

Benutzeravatar
Ronny
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 133
Registriert: 18. Nov 2005 14:33
Wohnort: IGD

Re: Inline-Assembler

Beitrag von Ronny »

majias hat geschrieben: Muss man die Matrix und den Vektor als Input und den Ergebnisvektor als Output zuweisen?
Da das Ergebnis ein Array ist, empfiehlt es sich die Adresse des Ergebnisvekors als Input zu uebergeben.
Diese Adresse verwenden Sie dann im Assemblercode um auf die verschiedenen Eintraege zuzugreifen.
majias hat geschrieben: Muss man den Code aus der 1a) eigentlich noch stark verändern für die 1b) oder kann man ihn mehr oder weniger mit copy & paste übernehmen?
Man kann den Code zu grossen Teilen uebernehmen. Ich sage natuerlich nicht welche Teile.

nairolf
Erstie
Erstie
Beiträge: 18
Registriert: 31. Jul 2011 13:58

Re: Inline-Assembler

Beitrag von nairolf »

Ich bekomme das mit Inline auch noch nicht so wirklich hin.
Ich bekomme immer folgenden fehler:
"aufgabe.c:35: error: impossible constraint in âasmâ"

mache ich vielleicht hier schon was falsch?:

Code: Alles auswählen

#include <stdio.h>

main(){

  float mat[3][4] = {{-886.8, 0.0, -512.0, 0.0},
	  				 {0.0, 886.8, -512.0, 0.0},
					 {0.0, 0.0, -1.0, 0.0}};
  float vek[4] = {4.0, 3.0, 2.0, 1.0};
  float res[3];

 asm("movl $3, %%ecx;"
  ".for:"
[...]
  "loop .for;"
  : "=b" (res)
  : "d" (mat), "b" (vek), "b" (res)
  : "ebx", "ecx", "edx"
  );
	
printf("Der Ergebnisvektor enthaelt folgende Werte: %f, %f, %f\n", res[0], res[1], res[2]);
}
oder hat der Fehler irgend was damit zu tun, dass ich SSE also mit den %XMM.. arbeite, die ich ja nicht bei "list of clobbered registers" angeben muss, oder?

mw1039
Computerversteher
Computerversteher
Beiträge: 346
Registriert: 12. Apr 2011 12:18

Re: Inline-Assembler

Beitrag von mw1039 »

Ich weiss nicht, ob das nur ein Tippfehler von dir war, aber du weist sowohl vek als auch res an ebx zu:
nairolf hat geschrieben:: "d" (mat), "b" (vek), "b" (res)
Koennte sein, dass er das mit impossible constraint meint.

Benutzeravatar
Ronny
BASIC-Programmierer
BASIC-Programmierer
Beiträge: 133
Registriert: 18. Nov 2005 14:33
Wohnort: IGD

Re: Inline-Assembler

Beitrag von Ronny »

mw1039 hat geschrieben:Ich weiss nicht, ob das nur ein Tippfehler von dir war, aber du weist sowohl vek als auch res an ebx zu
Das ist schon mal ein impossible constraint.
Ein weiteres impossible constraint ist, dass ebx in der clobbered list steht, obwohl es schon als Inputregister deklariert wurde.

Antworten

Zurück zu „Archiv“