Robert Gawron

"Tak naprawdę, człowiek posiada tylko życiorys."

Simple 32bit Intel Linux compiler, part 1

Summary

This compiler works with subset off l33tlang’s assembler and produces as an output binary file that can be executed on Intel386, 32bits compatible processors, on Linux platform. It’s written in C, in objective way.

Abilities

  • compiling procedures
  • usage of Linux interrupts (now only one is implemnebted)
  • artithmentic operations (now, only addition)
  • stack operations

Downloads

How does it works?

This will be described in next parts, subscribe to RSS feed please ;-)

Instalation

Compiler works on Linux and requires libelfg0/, libelfg0-dev packages, Other tools/libs are usually reinstalled on most Linux distributions (gcc, make, ld, etc.)

Installation looks similar to many open source projects:

# (from project's root directory)
./configure
cd src
make
# (as a root)
make install

Thanks to czarodziej for help in better version of installation process!

Doxygen is used as a tool for building documentation, I’ve added rule to Makefile, so updates in documentation can be done automatically by typing in src directory:

make docs

Generated documentation is stored in docs directory.

Usage

I made a simple Makefile to automatize tests, take a look:

all:
	valgrind ./nativecompiler ./externals.asm
	objdump -D foo.o 
	ld -s -o foo ./foo.o  -lelf -I/lib/ld-linux.so.2 
	./foo

It runs compiler under supervision of valgrind (tool for searching for memory leaks), then it uses objdump to check content of compiled file. Next, it uses ld, to links compiled file with library, where stuff from <stdio.h> is (here can be also problems) and tries to run it. I’m linkink to ld-linux.so.2 because I’m trying to use externals procedures (it’s not full implemented yet).

Here is an example program in l33tlang assembly language:

main:
    push 5
    push 3
    add
    call foo
    int 0
    int 2
    ret
foo:
    ret
usa:
    ret

When I run it with my makefile I will see this content (.text section) of compiled file, and the result of execution is 8 (do you know why?).

Disassembly of section .text:

00000000 <_start>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	68 05 00 00 00       	push   $0x5
   8:	68 03 00 00 00       	push   $0x3
   d:	59                   	pop    %ecx
   e:	5b                   	pop    %ebx
   f:	01 cb                	add    %ecx,%ebx
  11:	e8 11 00 00 00       	call   27 
  16:	e8 0c 00 00 00       	call   27 
  1b:	90                   	nop    
  1c:	b8 01 00 00 00       	mov    $0x1,%eax
  21:	cd 80                	int    $0x80
  23:	89 ec                	mov    %ebp,%esp
  25:	5d                   	pop    %ebp
  26:	c3                   	ret    

00000027 :
  27:	55                   	push   %ebp
  28:	89 e5                	mov    %esp,%ebp
  2a:	89 ec                	mov    %ebp,%esp
  2c:	5d                   	pop    %ebp
  2d:	c3                   	ret    

0000002e :
  2e:	55                   	push   %ebp
  2f:	89 e5                	mov    %esp,%ebp
  31:	89 ec                	mov    %ebp,%esp
  33:	5d                   	pop    %ebp
  34:	c3                   	ret    

Both of those file are stored in tests directory.

Conclusions

  • first of all, writting simple compiler isn’t so hard, it’s more a matter of patience in studying specifications, that skills.

External links