--- /dev/null
+ .file "asmb.c"
+ .text
+.globl asmb
+ .type asmb, @function
+asmb:
+.LFB2:
+ xor %rdx, %rdx
+ xor %ecx, %ecx
+
+ //soll einfach null sein
+ pxor %xmm14, %xmm14
+
+.nextround:
+ /*init %xmm8 mit "'Z' + 1 + min_t - 'A'" fuer jedes byte
+ * 'Z' + 1 + min_t - 'A' = 90 + 1 - 128 - 65 = -102
+ * 102 = 01100110
+ * ~102 = 10011001
+ * (~102)+1 = 10011010 = 0x9A */
+ mov $0x9a9a9a9a9a9a9a9a, %rax
+ movq %rax, %xmm15
+ movddup %xmm15, %xmm8
+
+ //init %xmm9 mit "'a'-'A'= 97-65 = 32 = 0x20
+ mov $0x2020202020202020, %rax
+ movq %rax, %xmm15
+ movddup %xmm15, %xmm9
+
+ //speicheradresse des pointers zeigt auf 16*8 feld = 128bit
+ movdqu (%rdi, %rdx, 8), %xmm11
+ movdqu (%rdi, %rdx, 8), %xmm12
+
+ /*addiere in %xmm11 "min_t-'A'"
+ * = -128 - 65 = 63 = 0x3f */
+ mov $0x3f3f3f3f3f3f3f3f, %rax
+ movq %rax, %xmm15
+ movddup %xmm15, %xmm10
+
+ //c+min_t-'A'
+ paddb %xmm10, %xmm11
+
+ /*"Packed COMpare Greater Than (Byte)"
+ * X = 'Z' + 1 + min_t - 'A' > c + min_t - 'A' ? 0xff : 0
+ * achtung beim intuitiven lesen des befehles. 'kleiner'
+ * ist mit 'groesser' vertauscht und vice versa */
+ pcmpgtb %xmm11, %xmm8
+
+ //Y = min(X, 'a' - 'A')
+ pminub %xmm9, %xmm8
+
+ //c += Y
+ paddb %xmm8, %xmm12
+
+ //retuniere an die richtige speicheradresse
+ movapd %xmm12, (%rdi, %rdx, 8)
+
+ //ist ein byte groesser als 0? dann steht 0xff drin
+ pcmpeqb %xmm14, %xmm12
+ //hol die MSBs aller bytes raus
+ pmovmskb %xmm12, %ecx
+ inc %rdx
+ inc %rdx
+ //ist %ecx gleich null? dann die naechsten 16byte bitte
+ jecxz .nextround
+
+ mov %rdi, %rax
+ ret
+.LFE2:
+ .size asmb, .-asmb
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1
+.LSCIE1:
+ .long 0x0
+ .byte 0x1
+ .string "zR"
+ .uleb128 0x1
+ .sleb128 -8
+ .byte 0x10
+ .uleb128 0x1
+ .byte 0x3
+ .byte 0xc
+ .uleb128 0x7
+ .uleb128 0x8
+ .byte 0x90
+ .uleb128 0x1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1
+.LASFDE1:
+ .long .LASFDE1-.Lframe1
+ .long .LFB2
+ .long .LFE2-.LFB2
+ .uleb128 0x0
+ .align 8
+.LEFDE1:
+ .ident "GCC: (Debian 4.3.2-1.1) 4.3.2"
+ .section .note.GNU-stack,"",@progbits
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned char *asmb(unsigned char *s);
+
+unsigned char *asmb_ref(unsigned char *s)
+{
+ unsigned long i;
+ for (i=0; s[i]; i++) {
+ unsigned char c = s[i];
+ c += (c >= 'A' && c <= 'Z') ? 'a'-'A' : 0;
+ s[i] = c;
+ }
+ return s;
+}
+
+int main(int argc, char **argv) {
+ char *input1[]={"asdfA\0BCDEFGHKL5", "foofuuMUHkk\0AAAA",
+ "AbC\0AAAAAAAAAAAA", "BLA|MUHMKUH|KAA\0",
+ "ASDFASDFasdfasdfaBC\0AAAABBBBCCCC",
+ "ASDFASDFasdfasdfaBC0AAAABBBBCCCCmuhKA\0asASDFasdf"
+ /* 8 16 20 24 28 32 36 40 48 */
+ };
+ int len[] = {16,16,
+ 16,16,
+ 32,
+ 48};
+ char *output1;
+ char *output2;
+ char *input2;
+ char *input3;
+ int i, j;
+
+ for(i = 0; i < 6; i++) {
+ input2 = strdup(input1[i]);
+ input3 = strdup(input1[i]);
+ output1 = (char *)asmb_ref((unsigned char *)(input2));
+ output2 = (char *)asmb((unsigned char *)(input3));
+
+ printf("\n");
+#if 0
+ if(memcmp(output1,output2, len[i])) {
+#else
+ if(strncmp(output1,output2, len[i])) {
+#endif
+ j = 0;
+ printf("Testfall falsch; Input war: \"%s\"\n", input1[i]);
+ printf("erwartet:\n\t\"%s\"\ntatsaechliches Ergebnis:\n\t\"%s\"\n", output1, output2);
+#if 0
+ printf("0x");
+ for(j = 0; j < 16; j++)
+ printf("%02X", output2[j]);
+ printf("\n");
+#endif
+ } else {
+ printf("Testfall \"%s\" passt.\n", output1);
+ }
+
+ free(input2);
+ free(input3);
+ }
+
+ return 0;
+}
+