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