From 01177f7324b9a21c0867434c68e93b98ed4eab22 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Tue, 3 Jan 2017 12:52:59 +0100 Subject: [PATCH] mescc: Have micro-mes print argc. * module/language/c99/compiler.mes (accu->ident): New function. (statement->text+symbols+locals): Use it to implement initialization with immediate, local. (_start): Call main with argc,argv [WAS: 0,0]. * module/mes/libc-i386.mes (i386:push-accu, i386:accu->local): New functions. * module/mes/libc-i386.scm: Export them. * doc/examples/micro-mes.c (main): Return argc as exit status. --- module/language/c99/compiler.mes | 56 +++++++++++++++++++++++- module/mes/libc-i386.mes | 75 ++++++++++++++++++++++++++++++++ module/mes/libc-i386.scm | 3 +- scaffold/micro-mes.c | 5 ++- 4 files changed, 134 insertions(+), 5 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index bde92aab..905c8b98 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -112,6 +112,10 @@ (lambda (o) (i386:local->accu (assoc-ref locals o)))) +(define (accu->ident locals) + (lambda (o) + (i386:accu->local (assoc-ref locals o)))) + (define (ident->base locals) (lambda (o) (i386:local->base (assoc-ref locals o)))) @@ -225,6 +229,20 @@ symbols locals))) + ((array-ref (p-expr (fixed ,value)) (p-expr (ident ,name))) + (let ((value (string->number value))) + (make-text+symbols+locals + (append + text + (list + (lambda (s t d) + (append + ((ident->base locals) name) + (i386:local-assign (assoc-ref locals name) value) + (i386:mem-byte->accu))))) + symbols + locals))) + ((array-ref (p-expr (ident ,name)) (p-expr (ident ,index))) (make-text+symbols+locals (append @@ -251,6 +269,29 @@ symbols locals)) + ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (ident ,local)))))) + (let ((locals (acons name (1+ (or (and=> (member 1 (map cdr locals)) length) 0)) locals))) + (make-text+symbols+locals + (append + text + (list (lambda (s t d) + ((ident->accu locals) local) + ((accu->ident locals) name)))) + symbols + locals))) + + ((decl (decl-spec-list (type-spec (typename ,type))) (init-declr-list (init-declr (ident ,name) (initzer (p-expr (ident ,local)))))) + (let ((locals (acons name (1+ (or (and=> (member 1 (map cdr locals)) length) 0)) locals))) + (make-text+symbols+locals + (append + text + ((ident->accu locals) name) + (list (lambda (s t d) + ((ident->accu locals) local) + ((accu->ident locals) name)))) + symbols + locals))) + ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name)))) (let ((locals (acons name (1+ (or (and=> (member 1 (map cdr locals)) length) 0)) locals))) (make-text+symbols+locals text symbols locals))) @@ -360,8 +401,19 @@ ((statement->text+symbols+locals text+symbols+locals) (car statements))))))))) (define _start - (let* ((ast (with-input-from-string - "int _start () {int i;i=main (0,0);exit (i);}" + (let* ((argc-argv + (string-append ".byte" + " 0x89 0xe8" ; mov %ebp,%eax + " 0x83 0xc0 0x08" ; add $0x8,%eax + " 0x50" ; push %eax + " 0x89 0xe8" ; mov %ebp,%eax + " 0x83 0xc0 0x04" ; add $0x4,%eax + " 0x0f 0xb6 0x00" ; movzbl (%eax),%eax + " 0x50" ; push %eax + )) + (ast (with-input-from-string + + (string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}") parse-c99)) (functions (filter ast:function? (cdr ast)))) ;;(pretty-print ast (current-error-port)) diff --git a/module/mes/libc-i386.mes b/module/mes/libc-i386.mes index 05c5b0bf..be0ea9ab 100644 --- a/module/mes/libc-i386.mes +++ b/module/mes/libc-i386.mes @@ -44,6 +44,9 @@ (define (i386:ref-local n) `(#xff #x75 ,(- 0 (* 4 n)))) ; pushl 0x(%ebp) +(define (i386:push-accu) + `(#x50)) ; push %eax + (define (i386:push-arg s t d) (lambda (o) (cond ((number? o) @@ -65,6 +68,9 @@ #xc3 ; ret ))) +(define (i386:accu->local n) + `(#x89 #x45 ,(- 0 (* 4 n)))) ; mov ,%eax,-<0xn>(%ebp) + (define (i386:local->accu n) `(#x8b #x45 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%eax @@ -105,6 +111,26 @@ #xcd #x80 ; int $0x80 )) +;; (define (i386:_start s t d) +;; (let* ((prefix +;; `( +;; #x55 ; push %ebp +;; #x89 #xe5 ; mov %esp,%ebp + +;; ;;#x83 #xec #x10 ; sub $0x10,%esp -- 4 local vars + +;; #xe8 ,@(int->bv32 (- address 5 s)) ; call relative + +;; #xb8 #x04 #x00 #x00 #x00 ; mov $0x4,%eax +;; #xcd #x80 ; int $0x80 + +;; #xc9 ; leave +;; #xc3 ; ret +;; )) +;; (text-list (text->list t)) +;; (statement-offset (- (+ (length prefix) (length text-list)))) +;; (address (+ t (function-offset "main" s)))))) + (define (i386:write s t d) `( #x55 ; push %ebp @@ -127,3 +153,52 @@ (define (i386:test-jump n) `(#x84 #xc0 ; test %al,%al #x75 ,(if (>= n 0) n (- n 4)))) ; jne + +#! +int +strcmp (char const* a, char const* b) +{ + while (*a && *b && *a == *b) {*a++;b++;} + return *a == *b; +} +08048150 : + 8048150: 55 push %ebp + 8048151: 89 e5 mov %esp,%ebp + 8048153: eb 0d jmp 8048162 + + + 8048155: 8b 45 08 mov 0x8(%ebp),%eax + 8048158: 83 c0 01 add $0x1,%eax + 804815b: 89 45 08 mov %eax,0x8(%ebp) + 804815e: 83 45 0c 01 addl $0x1,0xc(%ebp) + + + 8048162: 8b 45 08 mov 0x8(%ebp),%eax + 8048165: 0f b6 00 movzbl (%eax),%eax + 8048168: 84 c0 test %al,%al + 804816a: 74 1a je 8048186 + + 804816c: 8b 45 0c mov 0xc(%ebp),%eax + 804816f: 0f b6 00 movzbl (%eax),%eax + 8048172: 84 c0 test %al,%al + 8048174: 74 10 je 8048186 + + 8048176: 8b 45 08 mov 0x8(%ebp),%eax + 8048179: 0f b6 10 movzbl (%eax),%edx + 804817c: 8b 45 0c mov 0xc(%ebp),%eax + 804817f: 0f b6 00 movzbl (%eax),%eax + 8048182: 38 c2 cmp %al,%dl + 8048184: 74 cf je 8048155 + + + 8048186: 8b 45 08 mov 0x8(%ebp),%eax + 8048189: 0f b6 10 movzbl (%eax),%edx + 804818c: 8b 45 0c mov 0xc(%ebp),%eax + 804818f: 0f b6 00 movzbl (%eax),%eax + 8048192: 38 c2 cmp %al,%dl + 8048194: 0f 94 c0 sete %al + 8048197: 0f b6 c0 movzbl %al,%eax + 804819a: 5d pop %ebp + 804819b: c3 ret +!# + diff --git a/module/mes/libc-i386.scm b/module/mes/libc-i386.scm index 1c6e9958..9d4075f5 100644 --- a/module/mes/libc-i386.scm +++ b/module/mes/libc-i386.scm @@ -27,7 +27,8 @@ (define-module (mes libc-i386) #:use-module (srfi srfi-1) #:use-module (mes elf) - #:export (i386:call + #:export (i386:accu->local + i386:call i386:exit i386:formal i386:function-preamble diff --git a/scaffold/micro-mes.c b/scaffold/micro-mes.c index f3c9731a..3a8d4184 100644 --- a/scaffold/micro-mes.c +++ b/scaffold/micro-mes.c @@ -124,8 +124,8 @@ strlen (char const* s) int strcmp (char const* a, char const* b) { - while (*a && *b && *a == *b) {*a++;b++;} - return *a == *b; + while (*a && *b && *a == *b) {a++;b++;} + return *a - *b; } int @@ -216,6 +216,7 @@ main (int argc, char *argv[]) eputs ("Strlen...\n"); puts ("Bye micro\n"); int i = strlen ("02013"); + int i = argc; return i; }