# HG changeset patch # User Markus Bröker # Date 1229187477 -3600 # Node ID d752cbe8208e71a4ab2b9a558e4c1ac739ebe7be # Parent 236f8f7470730ed40f7ba3fb7b99b8e358b3ecce asm and parser demos added committer: Markus Bröker diff --git a/asm/Makefile b/asm/Makefile new file mode 100644 --- /dev/null +++ b/asm/Makefile @@ -0,0 +1,39 @@ +CC=gcc -g -ggdb +CFLAGS=-Wall -O2 -Iinclude +LDFLAGS= +NASM=nasm -f elf -Iinclude/ +TARGET=stackinfo +OBJECTS=main.o get_sp.o + +.SUFFIXES: .c .asm + +.c.o: + @echo Compiling $< ... + @$(CC) -c $(CFLAGS) -o $@ $< + +.asm.o: + @echo Assembling $< ... + @$(NASM) $< -o $@ + +all: $(TARGET) decimal + +$(TARGET): $(OBJECTS) + @echo Linking $(OBJECTS) ... + @$(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +decimal: decimal.o + $(CC) $(CFLAGS) -o $@ $< + +.PHONY: clean uninstall + +clean: + rm -f $(TARGET) decimal *.o *~ + +install: $(TARGET) decimal + install -d ~/bin + install $(TARGET) decimal ~/bin + +uninstall: + rm -f ~/bin/decimal + rm -f ~/bin/$(TARGET) + diff --git a/asm/decimal.c b/asm/decimal.c new file mode 100644 --- /dev/null +++ b/asm/decimal.c @@ -0,0 +1,110 @@ +/** + * $Id: decimal.c,v 1.1.1.1 2008-04-28 17:32:52 mbroeker Exp $ + * $Source: /development/c/asm/decimal.c,v $ + * + */ + +#include +#include +#include +#include + +#define MAXBITS __WORDSIZE +#define MAXVALUE ULONG_MAX + +typedef unsigned long int ULONG; + +void usage (char *name) +{ + printf ("Usage: %s start [end] [base]\n", name); +} + +/* + * Computes the binary representation of a + * decimal value and returns the result + * in proper order and the number of digits + */ + +char *dec_to_base (ULONG decimal, int base, int *digits) +{ + char *encoded; + char swp; + int i; + + i = 0; + + if ((decimal > MAXVALUE)) { + perror ("VALUE TOO BIG"); + return NULL; + } + + if ((encoded = malloc ((MAXBITS) * sizeof (char))) == NULL) { + perror ("MALLOC ERROR"); + return NULL; + } + + while (decimal > base - 1) { + encoded[i++] = (decimal % base); + decimal /= base; + } + encoded[i++] = (decimal % base); + *digits = i; + + for (i = 0; i < *digits - 1; i++) { + swp = encoded[*digits - i - 1]; + encoded[*digits - i - 1] = encoded[i]; + encoded[i] = swp; + } + + return encoded; +} + +int main (int argc, char **argv) +{ + ULONG decimal, start, end; + int bits, base, i; + char *binaer; + + base = 2; + + if (argc == 2) { + start = atol (argv[1]); + end = start + 1; + } else if (argc == 3) { + start = atol (argv[1]); + end = atol (argv[2]); + } else if (argc == 4) { + start = atol (argv[1]); + end = atol (argv[2]); + base = atoi (argv[3]); + } else { + usage (argv[0]); + return EXIT_SUCCESS; + } + + if (!((start >= 0) && (end > start) && (base > 1))) { + usage ("Trottel"); + printf ("%ld\t%ld\t%d\n", start, end, base); + return EXIT_SUCCESS; + } + + printf ("\tVALUE \t\tDIGITS\t\t Encoded\n"); + printf ("----------------------------------------------------\n"); + + for (decimal = start; decimal < end; decimal++) { + if ((binaer = dec_to_base (decimal, base, &bits)) == NULL) { + return EXIT_FAILURE; + } + + printf ("%12ld %12d \t\t", decimal, bits); + + for (i = 0; i < bits; i++) { + printf ("%X", binaer[i]); + } + printf ("\n"); + + if (binaer) + free (binaer); + } + return EXIT_SUCCESS; +} diff --git a/asm/get_sp.asm b/asm/get_sp.asm new file mode 100644 --- /dev/null +++ b/asm/get_sp.asm @@ -0,0 +1,51 @@ +;; +;; $ID$ +;; $Source: /development/c/asm/get_sp.asm,v $ +;; +;; + +%include "asm/tools.inc" + +segment .data +label1 db "NASM Powered...", 10, 0 +reg_format db "EAX=%08x EBX=%08x ECX=%08x EDX=%08x", 10, 0 +st_format db "EBP=%08x ESP=%08x ESI=%08x EDI=%08x", 10, 10, 0 +trace_fmt db "[EBP-20] = %08x", 10, \ + "[EBP-16] = %08x", 10, "[EBP-12] = %08x", 10, \ + "[EBP- 8] = %08x", 10, "[EBP- 4] = %08x", 10, \ + "[EBP+ 0] = %08x", 10, "[EBP+ 4] = %08x", 10, \ + "[EBP+ 8] = %08x", 10, "[EBP+12] = %08x", 10, \ + "[EBP+16] = %08x", 10, "[EBP+20] = %08x", 10, 10, 0 + +segment .bss + savexp resd 1 ;; uninitialized dword value + ;; currently not used + +segment .text + global get_sp + +get_sp: + enter 4,0 ;; push ebp ;; Save Base-Pointer + ;; mov ebp, esp ;; Copy Stackpointer for !!local usage!! + ;; sub esp, 4 ;; Make room for 1 DWORD + + mov [ebp-4], esp ;; Store result in !! local variable !! + + push DWORD label1 + call printf + add esp, byte 4 ;; remove label1 from stack + + call stack_trace + + call reg_info + call stack_info + + call reg_info + call stack_info + + call stack_trace + + ;; clean up + mov eax, [ebp-4] ;; return local var + leave ;; mov esp, ebp pop ebp + ret ;; return eax diff --git a/asm/include/asm/tools.inc b/asm/include/asm/tools.inc new file mode 100644 --- /dev/null +++ b/asm/include/asm/tools.inc @@ -0,0 +1,66 @@ +;; +;; $Id: tools.inc,v 1.1.1.1 2008-04-28 17:32:52 mbroeker Exp $ +;; $Source: /development/c/asm/include/asm/tools.inc,v $ +;; + +extern printf + +reg_info: + enter 0, 0 ;; Do i need to reserve space or not? + + push DWORD edx + push DWORD ecx + push DWORD ebx + push DWORD eax + push reg_format + + call printf ;; printf modifies eax + mov eax, [esp+4] ;; restore eax + leave + ret + +stack_info: + enter 0, 0 ;; Do i need to reserve space or not? + push eax ;; save eax + + push DWORD edi + push DWORD esi + push DWORD esp + push DWORD ebp + push st_format + + call printf ;; printf modifies eax + add esp, 20 ;; move sp 5 dws forward + pop eax ;; restore eax + leave + ret + +stack_trace: + enter 0,0 + push eax + + push DWORD [EBP+20] + push DWORD [EBP+16] + + push DWORD [EBP+12] + push DWORD [EBP+8] + + push DWORD [EBP+4] + push DWORD [EBP+0] + + push DWORD [EBP-4] + push DWORD [EBP-8] + + push DWORD [EBP-12] + push DWORD [EBP-16] + push DWORD [EBP-20] + + push trace_fmt + + call printf + + add esp, 48 + pop eax + leave + ret + diff --git a/asm/main.c b/asm/main.c new file mode 100644 --- /dev/null +++ b/asm/main.c @@ -0,0 +1,49 @@ +/** + * $Id: main.c,v 1.1.1.1 2008-04-28 17:32:52 mbroeker Exp $ + * $Source: /development/c/asm/main.c,v $ + * + */ + +#include +#include +#include +#include + +#ifndef TIMEOUT +#define TIMEOUT 500 +#endif + +int get_sp (); + +void sigendian () +{ + unsigned short word = 0x1234; + unsigned char *p = (unsigned char *)&word; + + signal (SIGUSR1, sigendian); + printf ("%s Endian System\n", (p[0] == 0x34) ? "Little" : "Big"); +} + +void sigproc () +{ + signal (SIGINT, sigproc); + printf ("Stack-Pointer is at %08x\n", get_sp ()); +} + +void sigquit () +{ + printf ("Hmm... You got it, man!\n"); + exit (0); +} + +int main (int argc, char **argv) +{ + signal (SIGINT, sigproc); + signal (SIGUSR1, sigendian); + signal (SIGQUIT, sigquit); + + for (;;) + usleep (TIMEOUT); + + return EXIT_FAILURE; +} diff --git a/parser/Makefile b/parser/Makefile new file mode 100644 --- /dev/null +++ b/parser/Makefile @@ -0,0 +1,36 @@ +CC=gcc +LD=ld +YACC=bison -y +FLEX=flex +CFLAGS=-Wall -O2 -ansi +LDFLAGS= +INCLUDE=include +OBJECTS=main.o parser.o lexer.o +TARGET=parser + +.SUFFIXES: .c .yy .ll + +.c.o: + $(CC) -c $(CFLAGS) -I$(INCLUDE) $(CONFIG) $< + +.yy.c: + $(YACC) -d $< -o $@ + +.ll.c: + $(FLEX) -o $@ $< + +all: $(TARGET) + + +$(TARGET): $(OBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $@ + +.PHONY: distclean clean + +clean: + rm -f *.[oae]; + rm -f *~; + +distclean: + make clean + rm -f $(TARGET) diff --git a/parser/lexer.ll b/parser/lexer.ll new file mode 100644 --- /dev/null +++ b/parser/lexer.ll @@ -0,0 +1,23 @@ +/* + * $Id$ + * $URL$ + */ + +%{ + #include + #include "parser.h" +%} + +%% + +[0-9]+ { yylval = atoi(yytext); return DIGIT; } +[a-zA-Z] { yylval = yytext[0]; return LETTER; } +"+" return PLUS; +"-" return MINUS; +"*" return MUL; +"/" return DIV; +"("|")"|"=" return yytext[0]; +[ \t]+ ; +\n return yytext[0]; +. printf("FEHLER: %s\n", yytext); +%% diff --git a/parser/main.c b/parser/main.c new file mode 100644 --- /dev/null +++ b/parser/main.c @@ -0,0 +1,15 @@ +/** + * $Id: main.c 52 2008-01-10 00:19:40Z mbroeker $ + * $URL: http://localhost/svn/c/parser/trunk/main.c $ + * + */ + +#include + +extern int yyparse (); + +int main (int argc, char **argv) +{ + yyparse (); + return 0; +} diff --git a/parser/parser.yy b/parser/parser.yy new file mode 100644 --- /dev/null +++ b/parser/parser.yy @@ -0,0 +1,84 @@ +/* + * $Id$ + * $URL$ + */ + +%{ + #include + #include + + int regs[26]; + int base; + + int yyerror(); + int yylex(); +%} + +%start list +%token DIGIT LETTER +%left MINUS PLUS MUL DIV +%left UMINUS +%% + +list : /* empty */ + | list stat '\n' + | list error '\n' { yyerrok; }; + +stat : + expr { (void) printf( "RESULT: %d\n", $1 ); } + | LETTER '=' expr { regs[$1] = $3; } + ; + + expr : '(' expr ')' + { + $$ = $2; + } + | expr PLUS expr + { + $$ = $1 + $3; + } + | expr MINUS expr + { + $$ = $1 - $3; + } + | expr MUL expr + { + $$ = $1 * $3; + } + | expr DIV expr + { + $$ = $1 / $3; + } + | MINUS expr %prec UMINUS + { + $$ = -$2; + } + | LETTER + { + $$ = regs[$1]; + } + | number + ; + + number : DIGIT + { + $$ = $1; base = ($1==0) ? 8 : 10; + } + | number DIGIT + { + $$ = base * $1 + $2; + } + ; + +%% + +int yyerror() +{ + printf("ERROR\n"); + return 0; +} + +int yywrap() +{ + return 1; +}