2009-05-31 10 views
3

Wenn Sie Assembler-Code in ein C/C++ - Programm einbetten, können Sie Clobbering-Register vermeiden, indem Sie sie mit einer Push-Anweisung speichern (oder clobber-Liste des Compilers angeben).Embedding Assembly in C mit Compiler Finding Register für Sie

Wenn Sie die Assembly inline einbinden und den Overhead vermeiden wollen, indem Sie gecroubte Register drücken und aufstoßen, gibt es eine Möglichkeit, gcc Register für Sie auszuwählen (z. B. solche, die keine nützlichen Informationen enthalten).

+0

fügen Sie bitte das "Hausaufgaben" -Tag hinzu, bitte beachten Sie auch, dass dies keine Hausaufgaben-Website sein soll, also müssen Sie das, was Sie bisher haben, für andere Leute bereitstellen und bereitstellen der Rest. – none

+0

Nicht sicher, was du meinst. Dies ist eine theoretische Frage, daher gibt es bisher keinen "Code". – bugmenot77

+3

Warum gehen Sie davon aus, dass dies Hausaufgaben sind? Ich hatte nie Hausaufgaben, die mich fragen, wie man gcc benutzt. Das ist ein Problem, dem man begegnet, wenn man versucht, etwas in der realen Welt zu erreichen. – nosatalian

Antwort

9

Ja. Sie können angeben, dass eine bestimmte Variable (Eingabe oder Ausgabe) in einem Register gespeichert werden soll, Sie müssen jedoch kein Register angeben. Eine detaillierte Erklärung finden Sie unter this document. Im Wesentlichen sieht die Inline-Assembler wie folgt aus:

asm("your assembly instructions" 
     : output1("=a"), // I want output1 in the eax register 
     output2("=r"), // output2 can be in any general-purpose register 
     output3("=q"), // output3 can be in eax, ebx, ecx, or edx 
     output4("=A") // output4 can be in eax or edx 
     : /* inputs */ 
     : /* clobbered registers */ 
    ); 
+0

Danke! Ich übersprang diese Datei tatsächlich vor dem Posten, aber verpasste es. Nachdem ich mich lange Zeit genommen habe, um diese kleinen Abschnitte zu lesen, kann ich sehen, warum! Es ist nicht schön, aber es funktioniert. Danke noch einmal. – bugmenot77

0

Compiler intrinsics sind eine sehr nützliche Art und Weise der Montage und C/C++ Code zu mischen. Sie sind Deklarationen, die wie Funktionen aussehen, aber direkt zu einzelnen nativen Anweisungen kompilieren (über einen speziellen Fall innerhalb des Compilers). Dies gibt Ihnen viel Kontrolle über die Arbeit in Assembly, aber lässt das Register Färbung und Planung bis zum Compiler.

Ein Vorteil ist, dass Sie dann eine gewöhnliche C-Variable in eine intrinsische übergeben können und der Compiler sich darum kümmern muss, sie in das Register zu laden und andere Ops um sie herum zu planen. Zum Beispiel

struct TwoVectors 
{ 
    __m128 a; __m128b; 
} 

// adds two vectors A += B using the native SSE opcode 
inline void SimdADD(TwoVectors *v) 
{ 
    v->a = _mm_add_ps(v->a , v->b); // compiles directly to ADDSS opcode 
} 
0

OK, so kann ich keinen Kommentar über verlassen, aber ich bin mir ziemlich sicher, dass die richtige Syntax (verschieden von oben) ist:

asm ("your assembly instructions" 
    : "=a"(output1), 
     "=r"(output2), 
     "=q"(output3), 
     "=A"(output4) 
    : /* inputs */ 
    : /* clobbered registers */ 
); 

Obwohl Sie kann die Zuweisung von Eingabe- und Ausgaberegistern zu dem Compiler belassen, es gibt keine offensichtliche Möglichkeit, die Zuweisung von Scratch/Temp-Registern (dh verwendet für Zwischenwerte, aber keine Eingabe oder Ausgabe) an den Compiler zu belassen. Historisch habe ich sie nur explizit in der Clobber-Liste aufgelistet (z. B. "% xmm1", "% rcx"), aber ich denke, es wäre besser, sie als Ausgaben aufzulisten, damit der Compiler sie auswählen kann. Ich kenne keine Quelle, die dieses Problem definitiv angeht.