Inline Assembler in GCC (naked?)
-
Moin moin zusammen!
Bin noch recht neu in der Materie. Zur Zeit nutze ich Linux (Ubuntu 7.10) und Eclipse mit C(++)-Plugin, welches wiederum GCC nutzt.
Nun wollte ich ein Assembler-Programm portieren nach C. Klappt auch soweit, nur eine Funktion kriege ich nicht konvertiert.
Was solls, also einfach Inline-Assembler. Denkste, da die Funktion einen void-Pointer zurückgeben soll, wills nicht so einfach.Hier erstmal der Code:
void *SetBreak(void *newbreak) { asm("pushl %ebp\n\t" "movl %esp, %ebp\n\t" "movl $45, %eax\n\t" "movl 8(%ebp), %ebx\n\t" "int $0x80\n\t" "movl %ebp, %esp\n\t" "popl %ebp\n\t" "ret\n\t"); }
//Kann durchaus sein, dass das so sehr sehr hässlich ist
Deklariert habe ich die Funktion zusätzlich mit
void *SetBreak(void *newbreak) __attribute__ ((naked));
Nur leider ignoriert er das naked.
Zielplattform ist x86, deswegen vielleicht?Wie kann ich nun GCC dazu überreden, die Funktion void* zurückgeben zu lassen?
Oder muss ich da ganz anders rangehen?Vielen Dank schonmal im Voraus.
-
Vielleicht tut das RET nicht so gut:
void * SetBreak(void *newbreak){ asm( "pushl %ebp\n\t" "movl %esp, %ebp\n\t" "movl $45, %eax\n\t" "movl 8(%ebp), %ebx\n\t" "int $0x80\n\t" "movl %ebp, %esp\n\t" "popl %ebp\n\t" ); return; }
-
Halt dich doch an die Aufrufkonventionen. Folgender Text hilft dir vielleicht weiter http://www.nondot.org/sabre/os/files/Booting/CompilingBinaryFilesUsingACompiler.pdf
-
Das return in den C-Code zu schreiben bringt keine Besserung.
Danke trotzdemDie Aufrufkonvention kenne ich, Argumente in umgekehrter Reihenfolge auf den Stack (Wenn denn das gemeint ist).
Da naked nicht will, hab ich's mal so versucht:
void *SetBreak(void *newbreak) { void *retval = NULL; asm("movl $45, %eax\n\t" "movl 8(%ebp), %ebx\n\t" "int $0x80\n\t" "movl %eax, 12(%ebp)\n\t" ); return retval; }
Ich gehe davon aus, das GCC mir mein
pushl %ebp movl %esp, %ebp movl %ebp, %esp popl %ebp
selbst einfügt.
So und jetzt wirds lustig.
4(%ebp) sollte die Rücksprungadresse sein, 8(%ebp) der erste Funktionsparameter. Und da es davon bei meiner Funktion nur einen gibt, müsste 12(%ebp) retval sein.
Wenn ich mich damit grade irre, bitte korrigieren!Nichtsdestotrotz funkioniert die Funktion nicht, retval bleibt NULL. Habe jetzt mein Assembler-Tutorial diesbezüglich schon dreimal duchgewälzt, aber in Kombi mit GCC sieht es da wohl etwas anders aus?
-
void *SetBreak(void *newbreak) { void *retval; asm( "int $0x80\n\t" : "=a" ( retval ) : "a" ( 45 ), "b" ( newbreak ) ); return retval; }
Das ist wirklich das falsche Forum für so etwas.
-
Danke!
Muss ich mir wohl GCC-Inlineassembler mal genauer anschauenP.S.: Ich wusste auch nicht, wo ichs reintuen sollte, ist eigentlich Assembler, eigentlich C und eigentlich Compiler
:p
-
Für alle, die sich das mal selber antun wollen/müssen:
Ich habe das gefunden, sieht recht brauchbar aus.Und bei der Gelegenheit gleich nochmal danke!