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 ist
    
    template<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 auf

    call    resize_string
    

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


Anmelden zum Antworten