From 90689d22cccce853ab6cb7dd078baaa501afb777 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 26 Sep 2021 20:31:51 +0200 Subject: cc: - fixed zeroing of EDX before division if operating register was EAX - implemented simple itoa in assembly in putint operation --- miniany/cc.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 23 deletions(-) (limited to 'miniany/cc.c') 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 ); -- cgit v1.2.3-54-g00ecf