2016-04-22 9 views
2

Einfache Frage. Die Funktion asm in C wird verwendet, um Inline-Assembly in Ihrem Code auszuführen. Aber was bringt es zurück? Ist es das herkömmliche eax, und wenn nicht, was gibt es zurück?Ist __asm ​​{}; den Wert von eax zurückgeben?

+3

Es ist auf dem Compiler abhängt, aber AFAIK ist es keine Funktion, und es gibt nichts zurück, so 'int i = __asm__() 'ist nur ein ungültiges Konstrukt – myaut

+3

Welcher Compiler? Welcher Prozessor? Die meisten Prozessoren haben kein eax-Register. – atturri

+1

Wahr. Okay, vorausgesetzt, es ist Visual Studio Compiler (nicht sicher, welches ist das) und ein 32-Bit-Intel-Prozessor. – Delupara

Antwort

3

__asm__ selbst gibt keinen Wert zurück. Der C-Standard definiert nicht, wie __asm__ den Rückgabewert verarbeiten soll, daher kann das Verhalten zwischen Compilern unterschiedlich sein. Sie haben angegeben, dass Visual Studio-Beispiel gültig ist, Visual Studio jedoch __asm verwendet. __asm__ wird zumindest von GCC verwendet.

Visual Studio

Um das Ergebnis in einem C-Programm zu erhalten, sollten Sie Rückgabewert eax in dem Assembler-Code platzieren, und Rückkehr aus der Funktion. Der Aufrufer erhält als Rückgabewert den Inhalt eax.

Visual Studio 2015 documentation:

int power2(int num, int power) 
{ 
    __asm 
    { 
     mov eax, num ; Get first argument 
     mov ecx, power ; Get second argument 
     shl eax, cl  ; EAX = EAX * (2 to the power of CL) 
    } 
    // Return with result in EAX 
} 

GCC

GCC inline assembly HOWTO kein ähnliches Beispiel enthalten. Dies bedeutet wahrscheinlich, dass Sie die implizite Rückgabe nicht wie in Visual Studio verwenden können. Das HOWTO zeigt jedoch, dass Sie das Ergebnis in C-Variable innerhalb des Assemblyblocks speichern können und den Wert dieser Variablen nach dem Beenden des Assembly-Blocks zurückgeben können.

Ein Beispiel für eine String-Kopierfunktion, Rückkehr Wert von dest:

static inline char * strcpy(char * dest,const char *src) 
{ 
int d0, d1, d2; 
__asm__ __volatile__( "1:\tlodsb\n\t" 
         "stosb\n\t" 
         "testb %%al,%%al\n\t" 
         "jne 1b" 
        : "=&S" (d0), "=&D" (d1), "=&a" (d2) 
        : "0" (src),"1" (dest) 
        : "memory"); 
return dest; 
} 
2

Es ist unwahrscheinlich; pro der C99 spec unter J3 Implementierung definiert Verhalten:

Das ASM Schlüsselwort kann direkt in den Übersetzer Ausgang (6,8) zum Einfügen in Assemblersprache verwendet werden. Die häufigste Anwendung ist über eine Anweisung der Form:

asm (character-string-literal);

So ist es unwahrscheinlich, dass ein Implementierer mit einer Annäherung kommen wird, die sowohl die Assembler-Sprache in die Übersetzer Ausgabe einfügt und auch erzeugt ein zusätzlicher Zwischenverbindungscode, um ein bestimmtes Register als ein Rückgabeergebnis zu verdrahten.

Es ist ein Schlüsselwort, keine Funktion.

z. GCC verwendet die Constraint-Semantik vom Typ "=r", damit Sie in Ihrer Assembly Schreibzugriff auf eine Variable haben. Aber Sie stellen sicher, dass das Ergebnis am richtigen Ort ist.

Verwandte Themen