rpnifs/rpn_lib.asm
Yann Weber 5e2aa9971d Bugfix rpn_lib.asm
Frogot that rbx MUST be preserved :/
2023-08-10 17:08:25 +02:00

251 lines
3.4 KiB
NASM

; TODO Use memory area given in argument to preserve stack between calls
[bits 64]
; local variables macro
%define stack_size [rbp - 8]
%define stack_base [rbp - 16]
%define brkinit [rbp - 24]
%define args_ptr [rbp - 32]
%define stack_cur r11
; push & pop the RPN stack macros
; check if stack full, then push value
%macro rpn_push 1
inc stack_cur
cmp stack_cur, stack_size
jl %%end
xor stack_cur, stack_cur
%%end:
mov [r10 + stack_cur * 8], %1
%endmacro
; check if stack empty, then pop value
%macro rpn_pop 1
mov %1, [r10 + stack_cur * 8]
cmp stack_cur, 0
jg %%end
mov stack_cur, stack_size
%%end:
dec stack_cur
%endmacro
; define a label with code portion size
; and set global
%macro part_sz 1
%1_sz: dq $ - %1
global %1
global %1_sz
%endmacro
section .note.GNU-stack noalloc noexec nowrite progbits
section .data
rpn_exec:
; unsigned long int rpn_exec(unsigned long int stack_size, unsigned long args, unsigned long int *stack)
; rdi -> stack size (in values (64 bits))
; rsi -> args pointers
; rdx -> stack pointer or null
enter 32, 0
push rbx ; rbx MUST BE PRESERVED !!! (like r12 to r15 and rbp !)
mov stack_size, rdi
mov args_ptr, rsi
mov r10, rdx ; r10 is stack base
xor rdx, rdx
mov brkinit, rdx
cmp r10, 0
jne .nobrk
; if stack is NULL allocate using brk
mov rax, 0x0C
xor rdi, rdi ; get brk
syscall
mov brkinit, rax
mov rdi, stack_size
shl rdi, 3 ; mul 8
add rdi, rax
mov rax, 0x0C
syscall ; new brk
cmp rax, -1
jne .cont
leave
ret
.cont:
mov rcx, stack_size
mov rdi, brkinit
xor rax, rax
.bzero:
stosq
loop .bzero
mov r10, brkinit
.nobrk:
xor stack_cur, stack_cur ; r11 is stack item counter
part_sz rpn_exec
rpn_exec_ret:
rpn_pop rax
mov rdi, brkinit
cmp rdi, 0
jne .end
push rax
mov rax, 0x0C
mov rdi, brkinit
syscall
pop rax
.end:
pop rbx
leave
ret
part_sz rpn_exec_ret
rpn_value:
mov rax, strict qword 0x12345678
rpn_push rax
part_sz rpn_value
rpn_arg:
mov rax, strict qword 0x12345678
mov rsi, 8
mul rsi
mov rsi, args_ptr
add rsi, rax
mov rax, [rsi]
rpn_push rax
part_sz rpn_arg
rpn_add:
rpn_pop rax
rpn_pop rbx
add rax, rbx
rpn_push rax
part_sz rpn_add
rpn_sub:
rpn_pop rbx
rpn_pop rax
sub rax, rbx
rpn_push rax
part_sz rpn_sub
rpn_mul:
rpn_pop rbx
rpn_pop rax
mul rbx
rpn_push rax
part_sz rpn_mul
rpn_div:
rpn_pop rbx
rpn_pop rax
xor rdx, rdx
test rbx, rbx
jz .zerodiv
div rbx
jmp .end
.zerodiv: xor rax, rax
.end:
rpn_push rax
part_sz rpn_div
rpn_mod:
rpn_pop rbx
rpn_pop rax
xor rdx, rdx
test rbx, rbx
jz .zerodiv
div rbx
jmp .end
.zerodiv: xor rax, rax
.end:
rpn_push rdx
part_sz rpn_mod
rpn_neg:
rpn_pop rax
neg rax
rpn_push rax
part_sz rpn_neg
rpn_not:
rpn_pop rax
not rax
rpn_push rax
part_sz rpn_not
rpn_and:
rpn_pop rbx
rpn_pop rax
and rax, rbx
rpn_push rax
part_sz rpn_and
rpn_or:
rpn_pop rbx
rpn_pop rax
or rax, rbx
rpn_push rax
part_sz rpn_or
rpn_xor:
rpn_pop rbx
rpn_pop rax
xor rax, rbx
rpn_push rax
part_sz rpn_xor
rpn_shl:
rpn_pop rcx
rpn_pop rax
cmp rcx, 64
jge .zero
shl rax, cl
jmp .end
.zero:
xor rax, rax
.end:
rpn_push rax
part_sz rpn_shl
rpn_shr:
rpn_pop rcx
rpn_pop rax
cmp rcx, 64
jge .zero
shr rax, cl
jmp .end
.zero:
xor rax, rax
.end:
rpn_push rax
part_sz rpn_shr
rpn_xchg:
rpn_pop rbx
rpn_pop rax
rpn_push rbx
rpn_push rax
part_sz rpn_xchg
rpn_dup:
rpn_pop rax
rpn_push rax
rpn_push rax
part_sz rpn_dup
rpn_pop_op:
rpn_pop rax
part_sz rpn_pop_op
section .text