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 trotzdem 🙂

    Die 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?


  • Mod

    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 anschauen 🙄

    P.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! 🙂 😃


Anmelden zum Antworten