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