uskel/exit_123.s
2023-08-04 20:11:39 +02:00

71 lines
1.4 KiB
ArmAsm

# || -> 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