2008-09-14 10 views
46

Ich erinnere mich mit dem alten borland DOS Compiler zurück in den Tag Sie etwas tun könnte:Gibt es eine Möglichkeit, Assemblercode in C einzufügen?

asm { 
mov ax,ex 
etc etc... 
} 

Gibt es eine halbplattformunabhängig Weg, dies jetzt zu tun? Ich muss einen BIOS-Aufruf machen, also wenn es einen Weg gäbe, dies ohne asm-Code zu tun, wäre das für mich ebenso nützlich.

+0

Siehe auch die Links im [Inline-Assembly-Tag-Wiki] (https://Stackoverflow.com/tags/inline-assembly/info), um zu erfahren, wie man das richtig macht. Es ist schwer und der beste Vorschlag ist https://gcc.gnu.org/wiki/DontUseInlineAsm. Wenn es möglich ist, optimieren Sie, wann immer möglich, Ihren Quellcode, um dem Compiler zu helfen, besseren Code zu erstellen, anstatt Inline-Asm zu verwenden. (z. B. durch Betrachten der asm-Ausgabe des Compilers, um zu sehen, was nicht optimiert wird oder was falsch gemacht wird.) –

Antwort

54

Mit GCC

__asm__("movl %edx, %eax\n\t" 
     "addl $2, %eax\n\t"); 

Verwendung VC++

__asm { 
    mov eax, edx 
    add eax, 2 
} 
+0

C++ Builder von CodeGear unterstützt auch das Schlüsselwort __asm. – stukelly

+0

VS-Compiler unterstützt keine Inline-Assembly! Ich hatte mir vor ein paar Jahren den Finger verbrannt, um das zu tun! –

+2

@JayD: Der VS-Compiler unterstützt Inline-Assembly abhängig vom Ziel. Zum Beispiel wird 32-Bit x86 unterstützt; 64-Bit x86-64 ist nicht. –

4

Ein guter Start wäre diesen Artikel lesen, die über Inline-Montage in C/C sprechen ++:

http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx

Beispiel aus dem Artikel:

#include <stdio.h> 


int main() { 
    /* Add 10 and 20 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
       "movl $20, %ebx;" 
       "addl %ebx, %eax;" 
    ); 

    /* Subtract 20 from 10 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
        "movl $20, %ebx;" 
        "subl %ebx, %eax;" 
    ); 

    /* Multiply 10 and 20 and store result into register %eax */ 
    __asm__ ("movl $10, %eax;" 
        "movl $20, %ebx;" 
        "imull %ebx, %eax;" 
    ); 

    return 0 ; 
} 
9

In GCC gibt es mehr als das. In der Anweisung müssen Sie dem Compiler mitteilen, was geändert wurde, damit sein Optimierer nicht versagt. Ich bin kein Experte, aber manchmal sieht es so etwas wie diese:

asm ("lock; xaddl %0,%2" : "=r" (result) : "0" (1), "m" (*atom) : "memory"); 

Es ist eine gute Idee, einig Beispiel-Code in C zu schreiben, dann GCC bitten, eine Assembler-Liste zu erzeugen, dann diesen Code ändern.

2

Nicht-x86-Microsoft-Compiler unterstützen keine Inline-Assemblierung. Sie müssen die gesamte Funktion in einer separaten Assembly-Quelldatei definieren und an einen Assembler übergeben.

Es ist sehr unwahrscheinlich, dass Sie unter einem Protected-Mode-Betriebssystem in das BIOS wechseln können und die auf diesem System verfügbaren Funktionen verwenden sollten. Selbst wenn Sie sich im Kernel-Modus befinden, ist es wahrscheinlich unsicher - das BIOS wird möglicherweise nicht korrekt in Bezug auf den Betriebssystemstatus synchronisiert, wenn Sie dies tun.

+0

Mike, was meinen Sie mit "Nicht-x86-Microsoft-Compiler unterstützen keine Inline-Assembly", natürlich können Sie z. ARM (nicht-x86) Inline-Assembly, suchen Sie einfach danach. –

+1

"Inline-Assembly wird auf den ARM- und x64-Prozessoren nicht unterstützt." - https://docs.microsoft.com/en-gb/cpp/assembler/inline/inline-assembler. * Inline * Assembler bedeutet die Verwendung von '__asm' Blöcken und ich spreche speziell über Microsofts Compiler. Sie können weiterhin eine separate ASM-Datei erstellen, diese mit dem Microsoft-Assembler (ML/ML64/ARMASM) zusammenstellen und die resultierende OBJ mit einem C/C++ - Programm mit CL verknüpfen. Die anderen Antworten zeigen an, dass Sie eine Inline-Assemblierung mit anderen Compilern durchführen können. –