(FAQ - Ander...) Inline Assembler in GCC
-
Ich hatte angefangen in eine C-Source inline assembler nach der mir bekannten Syntax einzubinden:
char message[] = "Hallo wie geht es?"; _asm{ mov si, message }
GCC meckert und nach einem Blick in die FAQ sah ich, dass man das so machen muss:
char message[] = "Hallo wie geht es?"; asm("mov si, message");
Jetzt meckert er nicht mehr über die Syntax, sagt aber folgendes:
Error: too many memory references for 'mov'Was soll denn das heißen?
-
der GCC nutzt einen anderen Assembler Syntax, als der MSVC++. Der MSVC++ nutzt Intel-Syntax Assembler und der GCC nutzt den (IMHO besseren) AT&T Syntax. In der 3er Version kann man das aber mit einem Parameter ändern, weiss aber nicht genau wie (schau am besten mal in die GCC Doku)
-
Bei GCC sieht die Syntax noch ein bisserl anders aus.
#include <stdio.h> int main() { char message[] = "Hallo wie geht es?"; asm("movl %0, %%esi;"::"r"(message)); return 0; }
-
gibt es zu diesem Syntax irgendwo Doku?
-
Original erstellt von hackbert:
gibt es zu diesem Syntax irgendwo Doku?Die ersten beiden Links beschreiben zwar primär wie man mit dem GCC inline Assember für einen Atmel AVR Prozessor schreibt, aber die Syntax und Semantik wie man beim GCC inline Assembler in C oder C++ Quellcode schreibt ist ja auch für andere Prozessoren (z.B. Intel, PowerPC oder SPARC) gültig. Lediglich die zur Verfügung stehenden Mnemonics und Register unterscheiden sich.
Inline Asm http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/inline_asm.html
GCC-AVR Inline Assembler Cookbook http://www.egnite.de/ethernut/GCCAVRInlAsmCB.pdf
Brennan's Guide to Inline Assembly http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
Introduction to GCC Inline Asm http://la.kmv.ru/rmiyagi-inline-asm.txt
Linux Assembly HOWTO :: GCC Inline Assembly http://www.tldp.org/HOWTO/Assembly-HOWTO/gcc.html
Inline assembly for x86 in Linux http://www-106.ibm.com/developerworks/library/l-ia.html
Using Inline Assembly With gcc http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf
Linux Assembly : resources http://la.kmv.ru/resources.html
-
Vielen Dank!
-
Ich habe jetzt den Parameter für GCC gefunden, der Intel Syntax im Quellcode erlaubt. Allerdings kommen jetzt ganz viele Fehler. Mein Programm sieht so aus:
main() { char message[] = "Second stage booting"; asm("mov eax, 0x00000000"); }
Es kommen 26 Fehler bei der kompilierung (gcc -c testkernel.c -masm=intel) die ich hier jetzt nicht alle auflisten möchte. Sie wiederholen sich ziemlich oft:
Too many memory references for mov
Too many memory references for sub
junk 'PTR [ebp-x]' after expression, wobei x für mehrere Zahlen stehen kann...
-
wie heißt der parameter? wär doch bestimmt was für die faq.
-
Der Parameter heißt -masm=intel wahlweise auch -mintel-syntax
trotzdem funktioniert mein proggie net
-
versuchs doch mal mit 0 statt 0x0000000....
-
Original erstellt von hackbert:
Der Parameter heißt -masm=intel wahlweise auch -mintel-syntax
trotzdem funktioniert mein proggie netWenn ich das ganze mit AT&T Syntax schreibe, wird zwar fehlerfrei kompiliert. Das erzeugte Binary schmiert allerdings beim Starten mit einem Segment Fault ab.
int main() { char message[] = "Second stage booting"; asm("mov 0x0, %ax"); return 0; }
Der Absturz kommt hierbei durch die -- aus Programmsicht -- unerwartet Veränderung des Registers "ax" auf 0x00.
Eine Kleine Änderung des Programms, das keine Auswirkung auf den eigentlichen Registerinhalt von "ax" hat stürzt beispielsweise nicht ab.int main() { char message[] = "Second stage booting"; asm("mov %ax, %ax"); return 0; }
Du solltest also schon wissen, was du tust wenn du inline Assembler Befehle verwendest.
-
Ist schon klar. Eigentlich sollte message in si geschoben werden. Aus Testzwecken habe ich allerdings erstmal 0x00 in ax geschoben, nur um zu sehen, ob der Compiler das Zeug kompiliert. Eine Frage noch: wie gebe ich an, dass die Adresse von message in si soll?
-
Original erstellt von hackbert:
Ist schon klar. Eigentlich sollte message in si geschoben werden. Aus Testzwecken habe ich allerdings erstmal 0x00 in ax geschoben, nur um zu sehen, ob der Compiler das Zeug kompiliert. Eine Frage noch: wie gebe ich an, dass die Adresse von message in si soll?#include <stdio.h> int main() { char message[] = "Hallo wie geht es?"; /* Die Adresse der Variable "message" wird ist innerhalb der ** Assemblerbefehler als %0 zugreifbar. */ asm("movl %0, %%esi;"::"r"(message)); /* Wenn du statt der Adresse den Inhalt der Speicherzelle benötigst, ** dann musst du das ganze mit runden Klammern schreiben: ** ** asm("movl (%0), %%esi;"::"r"(message)); */ return 0; }
-
So, ich wollte nur noch weitere Posts abwarten, nun ab damit in die FAQ.