Visual C++: Template + Inline Assembler
-
Ich versuche gerade std::bitset nachzuproggen, um mal meine Assemblerkenntnisse aufzufrischen.
Die Klasse übernimmt als template-argument size_t N. Die Werte selbst werden in einem Array von Ints gespeichert, d.h. die Klasse besitzt einen Zeiger auf Ints.
Neben dem int*, besitzt die Klasse auch noch einen size_t, der die Anzahl an ints angibt, d.h. die einzige Möglichkeit an die ursprüngliche Anzahl an "Bits" zu kommen, ist N auszulesen.template<size_t N> struct bitset { size_t nInts_; int* pInts_;In C++ kein Problem. In Assembler allerdings schon, weil solche Statements verboten sind:
mov eax, N ; müsste eigentlich gehen, weil N size_t isttemplate<size_t N> void resize_string(string* str) // keine Methode, sondern nur eine Funktion { str->resize(N); } // ... template<size_t N> std::string bitset<N>::to_string() const { __asm { call resize_string ; gibt einen Fehler, obwohl die } }wie kann ich jetzt trotzdem an N gelangen, ohne einen weiteren size_t zu meinem bitset hinzuzufügen?
-
Das dürfte nicht gehen. Assembler und Templates vertragen sich nunmal nicht sonderlich gut. Speziell, weil Assembler nicht den geringsten Schimmer von Template Funktionalität hat.
Um es jetzt noch etwas deutlicher zu sagen, du rufst folgende Funktion aufcall resize_stringEs gibt aber keine Funktion resize_string. Es gibt nur das Template resize_string<size_t>. Dieses instanziert zu resize_string<10> oder resize_string<100> oder was auch immer. Ich wüsste nicht, wie man mit Assembler darauf zugreifen könnte. Mit Intel Syntax sicherlich nicht. Ich hoffe, du verstehst wo die Problematik liegt. Du kannst nur versuchen, alles so weit zu abstrahieren, dass Nicht-Template Routinen übrig bleiben, welche sich dann mit Assembler implementieren lassen.
Aber ehrlich gesagt, ich wüsste nicht, wieso man einen solchen Container überhaupt mit Assembler implementieren sollte. Zumindest unter C++. Um deine Assembler Kenntnisse aufzufrischen, gibt es sicherlich sinnvollere Sachen.
-
resize_string existiert so ja gar nicht. Eine entsprechende Funktion wird für jede Instanz von resize_string<N> vom Compiler erzeugt. Also musst du die Funktion vorher instanzieren.
schau dir mal folgendes Beispiel an
#include <iostream> template<std::size_t N> std::size_t f() { return N; } template<std::size_t N> void g() { typedef std::size_t (*func_t)(); func_t ff = f<N>; std::cout << std::hex << reinterpret_cast<void*>(ff) << '\n'; } int main() { g<5>(); g<6>(); }Mit dem Template-Parameter kannst du vielleicht tricksen. Wenn du auf enums zugreifen kannst, sollte folgendes vll helfen
template<std::size_t N> void foo() { enum { n=N }; asm { mov eax, n } }HTH viel spaß
-
kingruedi schrieb:
resize_string existiert so ja gar nicht. Eine entsprechende Funktion wird für jede Instanz von resize_string<N> vom Compiler erzeugt. Also musst du die Funktion vorher instanzieren.
ich weiß wie templates funktionieren. aber sowas hätte halt eben nur als methode von bitset geklappt.
Mit dem Template-Parameter kannst du vielleicht tricksen. Wenn du auf enums zugreifen kannst, sollte folgendes vll helfen
funzt! Vielen Dank.
-
kingruedi schrieb:
Mit dem Template-Parameter kannst du vielleicht tricksen. Wenn du auf enums zugreifen kannst, sollte folgendes vll helfen
Du kannst dafür auch static const Member benutzen. Das sollte eigentlich jeder aktuelle Compiler beherrschen und ist, im Gegensatz zu enum, kein Hack.