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
- click to download version described in this article
- actual version of project can be obtain from GitHub by:
git clone git://github.com/RobertGawron/l33tlang.git
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 <foo> 16: e8 0c 00 00 00 call 27 <foo> 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 <foo>: 27: 55 push %ebp 28: 89 e5 mov %esp,%ebp 2a: 89 ec mov %ebp,%esp 2c: 5d pop %ebp 2d: c3 ret 0000002e <usa>: 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
- 80386 Instruction Set - glossary about i386 instructions, more information may be obtained from processor specification (but it's far to much for such tiny compiler like described)
- Understanding ELF using readelf and objdump,
- Creating ELF relocatable object files in Linux - basic tutorial about libelf library.
Pingbacks
No pingbacks yetComments
Dlatego napisałem wprost, że to jest spartolone, dzięki za konkretne uwagi, się tym zajmę :)
Ah i makefile też jest do dupy, bo taki trick:
LIBS=$(pkg-config —libs libelf) CFLAGS=$(pkg-config —cflags libelf) ./configure
nie pomaga i do Makefila nie trafiaja LIBSy i CFLAGS.
Posłałem Ci maila z załącznikeim jak ja widzie configure.
dzięki, przyjrzę się temu jutro
edit: naniosłem Twoje zmiany, dzięki za pomoc!
ok, moje zastrzeżenia, nie dystrybutuj paczki wraz z config.cache, po co komuś innemu cache Twoich ustawień? Po drugie chyba ta paczka nie kompletna bo nie ma u mnie latex/Makefile.in przez co ./configure nie powodzi sie. Aha no i skoro wymagasz jakichś bibliotek to fajnie jakby configure to sprawdzało :)