# || -> cont .func main # push a new integer pushq $100 pushq $INT_code mov %rsp, %r11 # backup first arg # push another new integer pushq $23 pushq $INT_code mov %rsp, %r12 # backup second arg # push the plus push %r12 push %r11 pushq $2 pushq $plus mov %rsp, %r13 # backup plus # push a cont thunk for main_exit push %rsi pushq $1 pushq $main_exit # evaluate into main_exit mov %rsp, %rsi enter %r13 # exitcode -> | cont (unused, should be 0) | .func main_exit mov 0x8(%rsi), %rdi # result to syscall exitcode mov $0x3c, %rax # syscall 60 syscall # exit %rdi # | arg1 | arg2 | -> cont .func plus # push a thunk for finishing the plus push %rsi # cont push %rbp # ret (self) mov 0x18(%rbp), %rax push %rax # arg2 pushq $3 pushq $plus_step1 mov %rsp, %rsi # continue to the new thunk enter 0x10(%rbp) # evaluate arg1 # arg1 -> | arg2 | ret | cont | .func plus_step1 # this is guaranteed to be entered only once (it's a cont), so we can rewrite the thunk in place mov 0x10(%rbp), %rax movq $plus_fini, 0x00(%rbp) mov %rsi, 0x10(%rbp) mov %rbp, %rsi # continue on the rewritten thunk enter %rax # evaluate arg1 # arg2 -> | arg1 | ret | cont | .func plus_fini mov 0x8(%rsi), %rax # arg 2 mov 0x10(%rbp), %rsi # location of arg1 add 0x8(%rsi), %rax # arg 1 mov 0x18(%rbp), %rsi # save result to the original plus thunk mov %rax, 0x08(%rsi) movq $INT_code, 0x00(%rsi) enter 0x20(%rbp) # eval cont, returning %rsi