AT&T inline ASM



  • Hallo.

    Ich kenne mich leider nur mit dem Intel - Assembler Syntax aus, leider unterstützt der g++ ja so weit ich weiss nur AT&T Syntax. Aber ich werde daraus einfach nicht schlau.

    Könnte mir einer von euch, der die für mich noch unverstädliche AT&T Syntax beherrscht eine funktion schreiben die ein bsf und bsr für 64 bit variablen erledigt.

    So etwa:

    inline int mybsf(unsigned long long &i64)
    { __asm ...
    }

    Würde wircklich helfen.
    Danke im vorraus.



  • Ich verschieb dich in das Assembler-Forum, da es sich um keine Unix Frage handelt.

    Das Forum ist eigentlich dazu da, konkrete Fragen zu beantworten. Zeig doch mal, was du bisher versucht hast. (So krass ist der Unterschied nicht zwischen Intel und AT&T Syntax, in der ASM-FAQ findest du genug Links, die dir AT&T-Syntax erklären)



  • Ok, das hab ich jetzt glaube ich verstanden, aber eines macht mir noch immer Kopfzerbrechen: Wie spreche ich damit auch den oberen Teil einer 64 Bit variable (unsigned long long) an?

    Danke,!



  • Die Register sind immer 32 Bit breit.

    64 Bit Variablen müssen also in zwei Registern gespeichert werden.
    Beim VC++ sind das AFAIR eax und edx.

    Probier es doch einfach aus, viele Möglichkeiten gibt es nicht.



  • schau dir am besten mal an, was der GCC für Assembler Code generiert, beim Zugriff auf long long. Mit der -S Option kannst du an den Assembler Output kommen.



  • Danke!!!
    Hat schon nach ein paar kleinen Spielereien geklappt! 🙂
    Gibts da eigentlich noch was zu verbessern bezüglich der result Variable?

    #include <stdio.h>
    
    inline int myBSF64(const unsigned long long int ull);
    
    int main(int argc, char **argv)
    { unsigned long long int ull;
    
      ull=64ULL<<32;
      printf("%d\n", myBSF64(ull));
      ull=6676ULL;
      printf("%d\n", myBSF64(ull));
    
      return 0;
    }
    
    inline int myBSF64(const unsigned long long int ull)
    { int result;
      __asm__("movl -8(%%ebp), %%eax\n"
              "cmpl $0, %%eax\n"
              "je upper\n"
              "bsfl %%eax, %0\n"
              "jmp end\n"
              "upper:\n"
              "movl -4(%%ebp), %%eax\n"
              "bsfl %%eax, %0\n"
              "addl $32, %0\n"
              "end:\n"
                  : "=r"(result));
      return result;
    


  • Meine Frage passt zum Thema, also poste ich sie mal gleich hier rein. Es geht darum ohne extended inline asm Variablen ausserhalb des asm-Blocks anzusprechen. Nach "Brennan's Guide to Inline Assembly" geht das nur mit globalen statischen Variablen. Was ist aber nun wenn ich eine statische Variable in der Funktion selber deklariere. Dann ist diese dort auch global, jedenfalls auf den Scope bezogen in dem sich auch der asm-Block befindet.
    Kann mir jemand mal den Syntax geben, wie ich es schaffe die Variable mit movl zu füllen? Irgendwie funktioniert das bei mir überhaupt nicht. Ich bekomme immer nur "Error: too many memory references for `mov'" als Fehlermeldung vom Assembler zurückgeliefert.

    cya
    liquid



  • Hallo
    Lokale Vars werden auf dem Stack angelegt und können deshalb nicht einfach so als pointer verwendet werden. http://net.pku.edu.cn/~aoa/pcasm-book.pdf ist ein ganz gutes werk wo im unterabschnitt 4.7.4 Calculating addresses of local variables erklärt ist wie das funzt

    MFG
    Michi



  • Eine statische Variable die in einer Funktion deklariert ist, ist keine lokale Variable und wird auch nicht auf dem Stack angelegt.

    Von statischen Variablen, sein sie nun global oder funktionsintern sind beim Linken die Speicheradressen festgesetzt. Das komische ist nur, dass man globale statische Variablen im ASM-Code ohne Probleme ansprechen kann. Allerdings funzt das mit funktionsinternen statischen Variablen und auch globalen Variablen innerhalb eines Namespace nicht mehr. Das ist doch irgendwie komisch? Scheint wohl was mit dem Scoping zu sein, aber ich wüsste das gerne genauer.

    cya
    liquid



  • Sorry,
    Hab dein Posting nur so kürz überflogen du hast natürlich recht, warum das nicht funktioniert weiß ich nicht, warscheinlich löst der linker das symbol nicht richtig auf ich würde dann einfach einen Zeiger ins asm übergeben

    MFG
    Michael


Anmelden zum Antworten