Inline Assembler und GCC mit Pointern?!



  • Hallo zusammen,

    ich bin dabei einige Funktionen zu implementieren, bei denen ich stark auf shifts angewiesen bin. Ich möchte unbedingt sicherstellen, dass dabei die effizienteste Variante genutzt wird (konkret geht es um shifting mit rotation durch das carry flag).

    Ich habe also ein Array:
    shiftemich[6] was z.B. eine Position nach Links geschoben werden soll.

    Grundsätzlich habe ich ein wenig verstanden wie man aus C mit inline Assembler und GCC (AT&T Syntax) auf Variablen zugreift und diese verändert.

    Zum Beispiel in etwa so:

    int a=4, b=8;
    __asm__ __volatile__("mov %%ebx,%%eax		;\n"
    		:"=a"(a), "=b" (b)
    		 :"a"(a), "b"(b)
    		 );
    

    Leider ist es so, dass ich komplett mit Pointern arbeite, d.h. meine Funktion sieht so aus:
    ArrayRotation(typ *eingangselement)
    d.h. meine Elemente sind dann:
    eingangselement[0] [1] [2] usw ...

    Ein einfaches Substituieren der Variablen funktioniert jedoch in dem Fall nicht. Was mache ich falsch?

    Danke für eure Hilfe 🙂



  • achja, die Elemente des Arrays sind vom Typ uint32_t.
    Ist damit überhaupt Inline-Assembler möglich?



  • Du musst dir die Adressierungsarten der CPU anschauen. Es gibt etwa ein Dutzend davon. Es gibt mehrere Möglichkeiten:

    movl $eingangselement, %ebx
    movl (%ebx), %eax    # eingangselement[0]
    movl 4(%ebx), %eax   # eingangselement[1]
    
    movl $eingangselement, %ebx
    movl $12, %ecx
    movl (%ebx, %ecx), %eax    # eingangselement[3]
    
    movl $eingangselement, %ebx
    movl $12, %ecx
    movl 4(%ebx, %ecx, 1), %eax    # eingangselement[4]
    
    movl $eingangselement, %ebx
    movl $3, %ecx
    movl (%ebx, %ecx, 4), %eax    # eingangselement[3]
    
    movl $eingangselement, %ebx
    movl $3, %ecx
    movl 4(%ebx, %ecx, 4), %eax    # eingangselement[4]
    
    movl $12, %ecx
    movl eingangselement(%ecx), %eax # eingangselement[3]
    
    movl $3, %ecx
    movl eingangselement(, %ecx, 4), %eax # eingangselement[3]
    

    hm... viel Spass 😃



  • *vergesst* was ich geschrieben habe, es war Müll 🙂



  • Hallo,

    ich habe mir die Originalfunktion angeschaut und versucht, nach C zurückzutransformieren. Wenn ich es richtig sehe, scheinst du so was zu machen:

    uint32_t data[3] = { ... };
    
    data[0] = ((data[1] & 0x00000001) << 31) ^ (data[0] >> 1);
    data[1] = ((data[2] & 0x00000001) << 31) ^ (data[1] >> 1);
    

    Ich würde sagen, die Verundung mit 0x00000001 ist überflüssig... Ansonsten bin ich am Ende mit meinem Latein 😞
    Vielleicht noch eine Empfehlung, kein Inline-Assembler zu verwenden. Schreibe am Besten einmal eine reine C-Funktion, parallel dazu eine reine Assembler-Funktion. Viel Glück 🙂



  • vci schrieb:

    *vergesst* was ich geschrieben habe, es war Müll 🙂

    Na toll... 😞


Anmelden zum Antworten