Assembler und C(++) mischen



  • Hallo!

    Wie kann man C++ und Assembler mischen?
    Ich habe zwar eine ungefähre Vorstellung davon (Object assemblieren, dem Linker übergeben, in C++ mit extern einbinden), aber ich hänge dabei bei folgendem:
    Wie kann ich Variablen übergeben?
    Ich möchte z.B. eine einfache Addier-Funktion in Assembler schreiben, bekomme aber die Variablen aus C++ nicht in den Akku.

    Aja, und weil wir gerade dabei sind noch eine Frage zum Thema:
    Kann es eigentlich zu Problemen kommen, wenn man mitten im C++ - Code einen Inline-Assembler-Block einbaut?
    Wenn man den Assembler-Code als eigene Funktion schreibt (so wie ich das eigentlich machen will) werden ja beim Aufruf eh die Register am Stack gesichert. Was aber wenn ich z.B. in C++ gerade in einer Schleife bin und im Inline-Assembler-Code an den Registern herumspiele? Kann es sein dass ich ihn damit irgendwie draus bringe?

    Danke!

    mfg



  • hallo auch.. das büchlein:
    assembler ge-packt empfiehlt:
    lege eine datei mit leerer methode (aber allen nötigen variablen) an. beispielsweise so:

    int iadd(int a, int b) {}
    

    dann kompilierst du es mit einem compiler deiner wahl mit -S (in meinem fall g++ -S dateiname.cpp) und öffnest die entstandene datei mit einem editor deiner wahl. füge deinen assembler code zwischen "@1:" und "@2:" ein:

    ;
    push ebp
    mov ebp, esp
    @1:
    @2:
    pop ebp
    ret
    

    solltest du parameter übergeben haben (deine variablen), sind diese in
    [ebp+8] (== erster parameter), [ebp+12] (== zweiter parameter), und so weiter
    abgelegt.

    zu risiken und nebenwirkungen braten sie ihren prozessor und lesen sie ihren hardwarefehler..

    gruss

    eviluser


  • Mod

    theoretisch kannst du methoden extern deklarieren und dann mittels assembler implementieren; allerdings ist zumindest mit vc++ die namensdekoration für thiscall aufrufe (also normale methoden) nicht dokumentiert, das wird also nichts

    für dokumentierte namensgebung musst du normale C funktionen entweder mit _stdcall oder _cdecl verwenden (ersteres ist vorzuziehen) - um nun efficienz zu sichern und trotzdem mit normalen methodenaufrufen zu arbeiten kannst du z.b. so vorgehen:

    header:

    class A
    {
        inline int TuIrgendWas(const int nA);  // das sei unsere zu implementierende methode
    };
    
    extern "C" int __stdcall A_TuIrgendWas(A* pThis, const int nA);
    
    inline int A::TuIrgendWas(const int nA)
    {
        return A_TuIrgendWas( this, nA );
    }
    

    assembler file:

    .586p
         .model    flat, stdcall
         option    casemap: none
    
         .code
    
    A_TuIrgendWas   PROC    PUBLIC, this: DWORD, nA: DWORD
    
    ; tu irgendwas hier, proc erzeugt automatisch korrekten prolog, so dass z.b.
                   mov     eax, nA
    ; funktioniert
    ; z.b.
                   lea     eax, [ eax + eax*4 ]
    
    ; int wird in eax zurückgegeben
    
                   ret
    
    ; ret erzeugt den nötigen prolog ebenfalls automatisch
    ; mit option prologue/epilogue kannst du das verhalten aber beeinflussen
    
    A_TuIrgendWas    ENDP
    
    end
    

    jetzt das asm file assemblieren, das objekt file dem linker bekannt machen



  • ich empfehle da die doku zum nasm ab kapitel 7.

    da ist sehr schön drinne beschrieben, wie man 16bit,32bit,16 & 32bit code schreibt und extern verwendbar macht. auch ist dort sehr schön beschrieben, wie man dies umgekert macht. (z.b. c/c++ funktionen in asm verwenden)

    http://mesh.dl.sourceforge.net/sourceforge/nasm/nasm-0.98.38-xdoc.zip
    ^^da gibt es die doku


Anmelden zum Antworten