rlwinm - C code



  • Hallo,

    ich versuche gerade Assembler zu verstehen.. in meinem c-programm habe ich sowas

    char string[12];
    // ... dann fülle ich den string
    int var2;
    var2 = (string[11] + string[12] * 2);
    

    wenn ich das im GDB Debugger disassemble(->otool), bekomme ich sowas wie

    extsb    r2,r2
    rlwinm   r2,r2,1,0,30
    add      r27,r0,r2
    mulhw    r29,r27,r29
    or       r4,r27,r27
    

    leider erschließt sich mir daraus nicht, die rlwinm funktioniert. kann das jemand mal genauer erklären? thx



  • Hast du einen PowerPC o.ä. ?

    http://news.software.ibm.com/doc_link/en_US/a_doc_lib/aixassem/alangref/rlwinm.htm#HDRIW480KEN

    Das scheint er zu sein, auch den Parametern nach.



  • ups. ja stimmt hatte ich vergessen zu sagen. hab einen powerpc (apple powermac g4)

    auf der seite bei examples steht: The following code rotates the contents of GPR 4 to the left by 2 bits and logically ANDs the result with a mask of 29 ones...

    # Assume GPR 4 contains 0x9000 3000.
    # Assume GPR 6 contains 0xFFFF FFFF.
    rlwinm 6,4,2,0,0x1D
    # GPR 6 now contains 0x4000 C000.
    # Under the same conditions
    # rlwinm 6,4,2,0xFFFFFFFC
    # will produce the same result.
    

    ok versteh ich nicht ganz. Wie mach ich das rotate left im C code? wie hängt das mit dem c code zusammen?



  • Hans Gerd schrieb:

    ups. ja stimmt hatte ich vergessen zu sagen. hab einen powerpc (apple powermac g4)

    Solche Sachen sollte man in einem Assemblerforum schon mal nebenbei erwähnen 😉

    Dein Code ist sowieso invalid, da du auf das 13. Element zugreifst, aber nur 12 Elemente im Array reserviert hast.
    Bei C zählt man immer bei 0 beginnend.

    Du kommst doch aus der Pascal/Delphi Ecke, stimmts ? 😉

    In C werden Zeichenketten nicht einfach mit dem + Operator verbunden.

    Ich finde es toll, dass du dafür interressierst, was der Compiler aus deinem Quelltext macht, aber vielleicht ist es dafür noch etwas zu früh und du solltest erstmal vertrauter mit C werden.

    EDIT:
    BTW: Es empfielt sich immer, die Optimierungen durch den Compiler explizit auszuschalten.
    Es lassen sich die Entsprechungen dann besser zuordnen, wenn keine "Tricks" angewandt werden.
    Und manche Compiler können sogar zu jedem Assemblerblock die entsprechende C-Zeile als Kommentar mit einfügen.



  • Hi

    so wie ich das verstanden hab macht der befehl folgendes.

    R2 = (R2 << 1) & 0xFFFFFFFFFFFF

    also der codeschnipsel String[12] * 2 Wiso er das jetzt noch mit 48 1en verundet kann ich dir nicht sagen. ggf ist das die rechengenauigkeit von Int auf deiner Maschine (ich hab die 30 hals hexzahl interpretiert und nicht als dezimalzahl entsprechend müste sich dann der and parameter verkleinern)

    gruss Termite



  • Ja stimmt,
    da hatte ich seinen Comment im Quellcode falsch gedeutet.

    Ich vermute, die Sache mit dem dem AND hat was mit dem Vorzeichenbit des int zu tun. Wenn die Zahl 1 Bit nach links geschoben wird, soll verhindert werden, dass das bit rechts neben dem Vorzeichen zum Vorzeichenbit wird.



  • Wie kommst du auf 48 1en? Das ist ein ganz simples <<1, mehr nicht.



  • Die Beschreibung des Mnemonics sagt aber etwas anderes aus.

    Es sind aber wohl nicht 48, es wird als Dezimal interpretiert.
    Siehe außerdem:

    ... AND the rotated data with a 32-bit generated mask ...



  • Ja, es wird mit 0xfffffffe verANDet, was aber keine Auswirkung hat, weil die letzte Stelle durch den Shift soundso 0 ist.



  • Hi

    ok man sollte die asm reff doch mal durchlesen. Hab nur kurtz das beispiel angeguckt.

    die ver ANDung mit 0xFFFFFFFE ist pflicht sonst würde ggf bit 31 an der Stelle 0 stehen und das wollen wir ja nicht. Der schiebt nicht nach links sondern rotiert. Wenn wir nur schieben wollen, müssen wir die bits die unten wieder reingeschoben wurden wieder ausblenden. Der befehl erschlägt somit 2 Aufgaben mit einer klappe. Schieben, Rotieren

    die correcte schreibweise in C müsste dan sein wenn wir <<< für das rotieren verwenden.

    c = ( c <<< 1) & 0xFFFF.FFFFE

    gruss



  • Gut, du hast Recht. Im Endeffekt ist es jedoch ein ganz banaler left shift.


Anmelden zum Antworten