I’ve decided to build a quick-and-dirty compiler following An Incremental Approach to Compiler Construction by Abdulaziz Ghuloum. I can build a bigger compiler later.
I’ve also decided to ditch continuation-passing style for this first draft. I’ll get my head around regular recursive implementations first.
I wanted to use stack-based parameter passing, but I gave up and am just using four registers instead. (I’ve forgotten a bit about how the stack works and I just wanted to move on.)
But using registers for argument passing turned out to be rather complicated, so now I’m back to using the stack.
The type checker/inference engine works alright, but I’m not using it at all right now. It uses bidirectional type checking with inference; I’ll probably rewrite this to do a full Hindley-Milner type checking/inference engine later.
I wonder if there’s a way to use the type information to make my assembler more efficient. (I bet there is; I’ll leave that for an enhancement.)
Write the C code to a file called foo.c
; example:
int main() {
int foo = 1;
int bar = 2;
return foo == bar;
}
Then compile with:
gcc -fomit-frame-pointer -S foo.c
That should give you a file named foo.s
that looks like:
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 15 sdk_version 10, 15, 4
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
movl $0, -4(%rsp)
movl $1, -8(%rsp)
movl $2, -12(%rsp)
movl -8(%rsp), %eax
cmpl -12(%rsp), %eax
sete %cl
andb $1, %cl
movzbl %cl, %eax
retq
.cfi_endproc
## -- End function
.subsections_via_symbols
addr of closure: 0x0000000100000d28
heap location: 0x0000000101008200
Verdict: I’m jumping to %rdi, not (%rdi); what would happen if I ran *(%rdi)
That works!
(lldb) re r General Purpose Registers: rax = 0x0000000101008200 rbx = 0x0000000000000000 rcx = 0x0000000000000000 rdx = 0x0000000000000010 rdi = 0x0000000101008200 rsi = 0x000000010011ba00 rbp = 0x00007ffeefbff720 rsp = 0x00007ffeefbff700 r8 = 0x0000000002000001 r9 = 0x0000000000000003 r10 = 0x9e3779b97f4a7c55 r11 = 0x0000000000000007 r12 = 0x0000000000000000 r13 = 0x0000000000000000 r14 = 0x0000000000000000 r15 = 0x0000000101008208 rip = 0x0000000100000d70 a.out`definition_end38349 + 49 rflags = 0x0000000000000216 cs = 0x000000000000002b fs = 0x0000000000000000 gs = 0x0000000000000000 (lldb) s Process 46879 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into frame #0: 0x0000000101008200 -> 0x101008200: subb %cl, 0x10000(%rip) 0x101008206: addb %al, (%rax) 0x101008208: addb %al, (%rax) 0x10100820a: addb %al, (%rax) Target 0: (a.out) stopped. (lldb) d -> 0x101008200: subb %cl, 0x10000(%rip) 0x101008206: addb %al, (%rax) 0x101008208: addb %al, (%rax) 0x10100820a: addb %al, (%rax) 0x10100820c: addb %al, (%rax) 0x10100820e: addb %al, (%rax) 0x101008210: addb %al, (%rax) 0x101008212: addb %al, (%rax) 0x101008214: addb %al, (%rax) 0x101008216: addb %al, (%rax) 0x101008218: addb %al, (%rax) 0x10100821a: addb %al, (%rax) 0x10100821c: addb %al, (%rax) 0x10100821e: addb %al, (%rax)