From: Bernhard Urban Date: Tue, 9 Mar 2010 18:21:45 +0000 (+0100) Subject: asma: formel "umgeformt" und im endeffekt einen befehl "gewonnen" (haha) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=uebersetzerbau-ss10.git;a=commitdiff_plain;h=0d97ed199d30d832052b90442e53d13c07ec55f0 asma: formel "umgeformt" und im endeffekt einen befehl "gewonnen" (haha) ausserdem hab ich die testumgebung vom ertl eingebaut und ein wenig erweitert --- diff --git a/asma/Makefile b/asma/Makefile index 6ce51e4..d2f9841 100755 --- a/asma/Makefile +++ b/asma/Makefile @@ -10,8 +10,10 @@ clean: rm -f $(NAME).o $(NAME) 1test: all + @echo " COMPILE callingconvention.c" + @gcc -c -fomit-frame-pointer -fno-defer-pop callingconvention.c @echo " COMPILE $<" - @gcc -pedantic -ansi -Wall -g -o $(NAME) $(NAME).s main.c -D_GNU_SOURCE + @gcc -Wall -g -o $(NAME) $(NAME).s main.c callingconvention.o -D_GNU_SOURCE @echo "execute ./$(NAME)" @./$(NAME) diff --git a/asma/asma.s b/asma/asma.s index d1202ce..9ea72d3 100644 --- a/asma/asma.s +++ b/asma/asma.s @@ -2,17 +2,17 @@ .section .rodata .align 128 -const9a: +const65: .rept 16 - .byte 0x9a + .byte 0x65 .endr const20: .rept 16 .byte 0x20 .endr -const3f: +constc0: .rept 16 - .byte 0x3f + .byte 0xc0 .endr .text @@ -20,37 +20,41 @@ const3f: .type asma, @function asma: .LFB2: - /*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 */ - movdqa const9a, %xmm8 + // folgendes kann umgeformt werden: + // (mathematisch ned ganz korrekt) + // X = 'Z' + 1 + min_t - 'A' > c + min_t - 'A' ? 0xff : 0 + // X = -102 > c + 63 ? 0xff : 0 + // X = c + 63 < -102 ? 0xff : 0 + // X = -(c + 63) > 102 ? 0xff : 0 + // X = -63 - c > 102 ? 0xff : 0 + // X = -63 - c - 1 > 102 - 1 ? 0xff : 0 + // X = -64 - c > 101 ? 0xff : 0 + // ... + // 101 = 0x65 + // -64 = 0xc0 - //speicheradresse des pointers zeigt auf 16*8 feld = 128bit + // speicheradresse des pointers zeigt auf 16*8 feld = 128bit movdqu (%rdi), %xmm11 - /*addiere in %xmm11 "min_t-'A'" - * = -128 - 65 = 63 = 0x3f - * c+min_t-'A' */ - paddb const3f, %xmm11 + // -64 - c + movdqa constc0, %xmm9 + psubb %xmm11, %xmm9 - /*"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 + // "Packed COMpare Greater Than (Byte)" + // achtung beim intuitiven lesen des befehles. 'kleiner' + // ist mit 'groesser' vertauscht und vice versa + pcmpgtb const65, %xmm9 - /*Y = min(X, 'a' - 'A') - * mit "'a'-'A'= 97-65 = 32 = 0x20 */ - pminub const20, %xmm8 + // Y = min(X, 'a' - 'A') + // mit 'a'-'A'= 97-65 = 32 = 0x20 + pminub const20, %xmm9 - //retuniere an die richtige speicheradresse + // c += Y + paddb %xmm9, %xmm11 + + // retuniere an die richtige speicheradresse mov %rdi, %rax - //c += Y - psubb const3f, %xmm11 - paddb %xmm11, %xmm8 - movdqu %xmm8, (%rax) + movdqu %xmm11, (%rax) ret .LFE2: diff --git a/asma/asma_ref.s b/asma/asma_ref.s deleted file mode 100644 index 1480455..0000000 --- a/asma/asma_ref.s +++ /dev/null @@ -1,52 +0,0 @@ - .file "asma_ref.c" - .text -.globl asma_ref - .type asma_ref, @function -asma_ref: -.LFB2: - movl $0, %ecx -.L4: - movzbl (%rdi,%rcx), %edx - leal -65(%rdx), %eax - cmpb $26, %al - sbbl %eax, %eax - andl $32, %eax - addl %edx, %eax - movb %al, (%rdi,%rcx) - addq $1, %rcx - cmpq $16, %rcx - jne .L4 - movq %rdi, %rax - ret -.LFE2: - .size asma_ref, .-asma_ref - .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 diff --git a/asma/callingconvention.c b/asma/callingconvention.c new file mode 100644 index 0000000..5ed4e52 --- /dev/null +++ b/asma/callingconvention.c @@ -0,0 +1,33 @@ +/* gcc -c -fomit-frame-pointer -fno-defer-pop callingconvention.c */ + +#include + +extern unsigned char *asma(unsigned char *s); + +/* geprueft werden callee gesicherte Register: rbx,r12-r15, + * rsp (stackptr), rbp (frameptr) */ + +#define CHECKNUM 0x1234567812345678 +unsigned char *asma_callchecking(unsigned char *s) +{ + register long x0 asm("%rbx")=CHECKNUM+0; + register long x1 asm("%r12")=CHECKNUM+1; + register long x2 asm("%r13")=CHECKNUM+2; + register long x3 asm("%r14")=CHECKNUM+3; + register long x4 asm("%r15")=CHECKNUM+4; + register long x5 asm("%rbp")=CHECKNUM+5; + static void* origsp; + void*newsp; + unsigned char *res; + asm("movq %%rsp,%0":"=g"(origsp):); + res=asma(s); + if(x0!=CHECKNUM+0) exit(11); + if(x1!=CHECKNUM+1) exit(12); + if(x2!=CHECKNUM+2) exit(13); + if(x3!=CHECKNUM+3) exit(14); + if(x4!=CHECKNUM+4) exit(15); + if(x5!=CHECKNUM+5) exit(16); + asm("movq %%rsp,%0":"=g"(newsp):); + if(origsp!=newsp) exit(30); + return res; +} diff --git a/asma/main.c b/asma/main.c index a228147..4d52115 100644 --- a/asma/main.c +++ b/asma/main.c @@ -1,33 +1,60 @@ #include #include #include +#include extern unsigned char *asma(unsigned char *s); +extern unsigned char *asma_callchecking(unsigned char *s); -unsigned char *asma_ref(unsigned char *s) +unsigned char *orig_asma(unsigned char *s) { int i; for (i=0; i<16; i++) { - unsigned char c = s[i]; - c += (c >= 'A' && c <= 'Z') ? 'a'-'A' : 0; + 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[]={"asdfABCDEFGHKL54", "foofuuMUHkk", "AbC", "BLA|MUHMKUH|KA"}; +static char ascii(char s) { + if(s < 0x20) return '.'; + if(s > 0x7E) return '.'; + return s; +} + +static void hexdump(void *d, int len) { + unsigned char *data; + int i, off; + data = (unsigned char*)d; + for (off=0; off=len) printf(" "); + else printf("%02x ",data[off+i]); + + printf(" "); + for(i=0; i<16; i++) + if((i+off)>=len) printf(" "); + else printf("%c",ascii(data[off+i])); + printf("\n"); + } +} + +int main2(void) +{ + char *input1[]={"asdfABCDEFGHKL54", "foofuuMUHkk", "AbC", "BLA|MUHMKUH|KA", "XZY"}; char *output1; char *output2; char *input2; char *input3; int i, j; - int off[] = {2,0,0,0}; + int off[] = {2,0,0,0,0}; - for(i = 0; i < 4; i++) { + for(i = 0; i < 5; i++) { input2 = strdup(input1[i]); input3 = strdup(input1[i]); - output1 = (char *)asma_ref((unsigned char *)(input2 + off[i])); + output1 = (char *)orig_asma((unsigned char *)(input2 + off[i])); output2 = (char *)asma((unsigned char *)(input3 + off[i])); output1[16]='\0'; @@ -38,12 +65,6 @@ int main(int argc, char **argv) { 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); } @@ -55,3 +76,122 @@ int main(int argc, char **argv) { return 0; } +void printchar(unsigned char c) +{ + if (c<' ' || c>126 || c=='"') + printf("\\x%02x",c); + else + putchar(c); +} + +void printarray(unsigned char* bufstart, int buflength, unsigned char* s) +{ + int i; + unsigned char *p=s-16; + unsigned long pl; + unsigned long l=16; + if (pbufstart+buflength) + pl=bufstart+buflength-p; + printf("%p=",p); + for(i=0; ;i++) { + if (p+i==s+l) + printf("\""); + if (!(i