asm and parser demos added
authorMarkus Bröker <mbroeker@largo.dyndns.tv>
Sat, 13 Dec 2008 17:57:57 +0100
changeset 5 d752cbe8208e
parent 4 236f8f747073
child 6 c3dc3eb3b541
asm and parser demos added committer: Markus Bröker <mbroeker@largo.homelinux.org>
asm/Makefile
asm/decimal.c
asm/get_sp.asm
asm/include/asm/tools.inc
asm/main.c
parser/Makefile
parser/lexer.ll
parser/main.c
parser/parser.yy
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)
+
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#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;
+}
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
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
+
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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#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;
+}
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)
new file mode 100644
--- /dev/null
+++ b/parser/lexer.ll
@@ -0,0 +1,23 @@
+/* 
+ *  $Id$
+ * $URL$
+ */
+
+%{
+	#include <stdio.h>
+	#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);
+%%
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 <stdio.h>
+
+extern int yyparse ();
+
+int main (int argc, char **argv)
+{
+    yyparse ();
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/parser/parser.yy
@@ -0,0 +1,84 @@
+/* 
+ *  $Id$
+ * $URL$
+ */
+
+%{
+   #include <stdio.h>
+   #include <ctype.h>
+
+   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;
+}