summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-09-26 20:31:51 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2021-09-26 20:31:51 +0200
commit90689d22cccce853ab6cb7dd078baaa501afb777 (patch)
treee1a1f3b6e106fbbd52888c889b09a519d86545c6
parentd0491186abedd36a6e065e97bf29eaaf87f6f95c (diff)
downloadcompilertests-90689d22cccce853ab6cb7dd078baaa501afb777.tar.gz
compilertests-90689d22cccce853ab6cb7dd078baaa501afb777.tar.bz2
cc:
- fixed zeroing of EDX before division if operating register was EAX - implemented simple itoa in assembly in putint operation
-rw-r--r--miniany/README4
-rw-r--r--miniany/cc.c101
-rw-r--r--miniany/test1.c3
3 files changed, 84 insertions, 24 deletions
diff --git a/miniany/README b/miniany/README
index 033f3d4..6367011 100644
--- a/miniany/README
+++ b/miniany/README
@@ -73,6 +73,10 @@ complex things into our own compiler.
* https://github.com/lotabout/write-a-C-interpreter/blob/master/tutorial/en/: tutorial
based on C4 how to build a C interpreter, explains nicely details in C4.
+* https://github.com/felipensp/assembly/blob/master/x86/itoa.s,
+ https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.html,
+ putint for early debugging
+
* documentation
* "Compiler Construction", Niklaus Wirth
* https://github.com/DoctorWkt/acwj: a nice series on building a C compiler,
diff --git a/miniany/cc.c b/miniany/cc.c
index b9cfe5a..acba6df 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -702,6 +702,11 @@ int genDiv( struct Generator *generator, int leftreg, int rightreg )
int reg;
if( leftreg == EAX ) {
+ if( !generator->regFree[EDX] ) {
+ genSaveReg( generator, EDX );
+ }
+ putstring( "mov edx, 0" );
+ putnl( );
reg = genBinary( "div", generator, leftreg, rightreg, 1 );
} else {
if( !generator->regFree[EAX] ) {
@@ -795,34 +800,85 @@ void genPrologue( struct Compiler *compiler )
putstring( "format binary" ); putnl( );
putstring( "use32" ); putnl( );
putstring( "org $1000000" ); putnl( );
- putstring( "jmp _start" ); putnl( );
+ putstring( "jmp _start" ); putnl( );
putstring( "putint:" ); putnl( );
+ putstring( "mov esi, 0xa" ); putnl( );
+ putstring( "lea edi, [putint_string_fmt]" ); putnl( );
+ putstring( "add edi, 9" ); putnl( );
+ putstring( "itoa_loop:" ); putnl( );
+ putstring( "mov edx, 0" ); putnl( );
+ putstring( "div esi" ); putnl( );
+ putstring( "add edx, 0x30" ); putnl( );
+ putstring( "mov byte [edi], dl" ); putnl( );
+ putstring( "dec edi" ); putnl( );
+ putstring( "cmp eax, 0" ); putnl( );
+ putstring( "jnz itoa_loop" ); putnl( );
putstring( "mov eax, 4" ); putnl( );
putstring( "mov ebx, 1" ); putnl( );
/* TODO: itoa in assembly (yuck!) and print resulting string */
- putstring( "mov ecx, putint_string" ); putnl( );
+ putstring( "mov ecx, putint_string_fmt" ); putnl( );
/* TODO: compute length with a assemble time function sizeof or so.. */
- putstring( "mov edx, 13" ); putnl( );
+ putstring( "mov edx, 11" ); putnl( );
putstring( "int 0x80" ); putnl( );
- putstring( "ret 4" ); putnl( );
+ putstring( "ret" ); putnl( );
putstring( "_start:" ); putnl( );
-
+
/*
- __asm__ volatile( "\
- push %%ebx\n\
- push %%ecx\n\
- push %%edx\n\
- mov %1, %%eax\n\
- mov %2, %%ebx\n\
- mov %3, %%ecx\n\
- mov %4, %%edx\n\
- int $0x80\n\
- mov %%eax, %0\n\
- pop %%edx\n\
- pop %%ecx\n\
- pop %%ebx\n" : "=m"( retval ) : "m"( id ), "m"( arg0 ), "m"( arg1 ), "m"( arg2 )
- : "eax", "ebx", "ecx", "edx" );
- */
+
+fmt: .string "%s\n"
+
+.lcomm converted, 10
+
+
+ .section .text
+
+.global _start
+
+_start:
+
+ xorl %ecx, %ecx
+ xorl %edi, %edi
+ movl $NUMBER, %eax
+
+itoa_loop:
+ # Limpa para divisão
+ xorl %edx, %edx
+
+ movl $10, %esi
+
+ # Agora nós temos o quociente em %eax
+ # e o resto da divisão em %edx
+ idiv %esi
+
+ # Convertendo para a representação em ASCII
+ addl $48, %edx
+
+ pushl %edx
+ incl %ecx
+
+ xorl $0, %eax
+ jnz itoa_loop
+
+rev_loop:
+ popl %eax
+ movl %eax, converted(, %edi, 1)
+ incl %edi
+ decl %ecx
+
+ cmpl $0, %ecx
+ jnz rev_loop
+
+ pusha
+ pushl $converted
+ pushl $fmt
+ call printf
+ addl $8, %esp
+ popa
+
+ # Exiting
+ movl $1, %eax
+ int $0x80
+ */
}
void genEpilogue( struct Compiler *compiler )
@@ -836,8 +892,8 @@ void genEpilogue( struct Compiler *compiler )
genAddGlob( compiler->generator, sym->name );
sym = sym->next;
}
- putstring( "putint_string:" ); putnl( );
- putstring( "db \"putint test \", 10, 0" ); putnl( );
+ putstring( "putint_string_fmt:" ); putnl( );
+ putstring( "db \" \", 10, 0" ); putnl( );
}
/* parser */
@@ -1049,7 +1105,6 @@ void parsePutint( struct Compiler *compiler )
node = parseExpression( parser, 0 );
parserExpect( parser, S_SEMICOLON, ";" );
generateFromAST( compiler->generator, node, NOREG );
- putstring( "push eax" ); putnl( );
putstring( "call putint" ); putnl( );
genFreeAllRegs( compiler->generator );
freeASTnode( node );
diff --git a/miniany/test1.c b/miniany/test1.c
index d7015e2..707ff16 100644
--- a/miniany/test1.c
+++ b/miniany/test1.c
@@ -4,5 +4,6 @@ int i;
int j;
i = 12+25/5-2*3; // 25/5 -> 5, 12+5 -> 17, 2*3 -> 6, 17-6 -> 11
-j = i/3+3*4; // 11 / 3 -> 3, 3*4 -> 12, 3+12 -> 15
putint i;
+j = i/3+3*4; // 11 / 3 -> 3, 3*4 -> 12, 3+12 -> 15
+putint j;