(param-register i)))
captured (range 0 (length captured)))
-
; then codegen the arguments and move them into the next param registers
(for-each
(lambda (e i)
(for-each codegen-lambda lambdas)
(emit "_start:")
+
+ ; allocate some heap memory
+ (emit "mov $9, %rax") ; mmap
+ (emit "xor %rdi, %rdi") ; addr = null
+ (emit "movq $1024, %rsi") ; length = 1kb
+ (emit "movq $0x3, %rdx") ; prot = read | write = 0x2 | 0x1
+ (emit "movq $0x22, %r10") ; flags = anonymous | private = 0x20 | 0x02
+ (emit "movq $-1, %r8") ; fd = -1
+ (emit "xor %r9, %r9") ; offset = 0
+ (emit "syscall")
+
+ ; %rax now contains pointer to the start of the heap
+ ; keep track of it
+ (emit "movq %rax, (heap_start)")
+
(emit "movq %rsp, %rbp") ; set up the base pointer
(codegen-expr xform-prog 0 '())
(emit "mov $60, %rax")
(emit "syscall")
- (emit "\t.data")
+ (emit ".data")
+
+ (emit "heap_start:")
+ (emit "\t.quad 0")
(for-each emit-string-data strings)))
(with-output-to-file tmp-path
(lambda () (codegen program)))
(system (format "clang -nostdlib /tmp/a.s -o ~a" output))))
+
+; NOTES
+; syscalls in linux use the following arguments for syscall instruction:
+; %rax = syscall #
+; %rdi = 1st arg
+; %rsi = 2nd arg
+; %rdx = 3rd arg
+; %r10 = 4th arg
+; %r8 = 5th arg
+; %r9 = 6th arg