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)