2025-12-26 15:50:37 +01:00
|
|
|
# Reserve 64 bytes in .bss
|
|
|
|
|
# persistent: resb 64
|
|
|
|
|
|
|
|
|
|
# : p@ ( offset -- n )
|
|
|
|
|
:asm p@ {
|
|
|
|
|
mov rax, [r12] ; offset
|
|
|
|
|
lea rbx, [rel persistent]
|
|
|
|
|
add rax, rbx ; address = persistent + offset
|
|
|
|
|
mov rax, [rax] ; load value
|
|
|
|
|
mov [r12], rax ; store on stack
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : p! ( value offset -- )
|
|
|
|
|
:asm p! {
|
|
|
|
|
mov rbx, [r12] ; offset
|
|
|
|
|
add r12, 8
|
|
|
|
|
mov rax, [r12] ; value
|
|
|
|
|
lea rcx, [rel persistent]
|
|
|
|
|
add rcx, rbx ; address = persistent + offset
|
|
|
|
|
mov [rcx], rax ; store value
|
|
|
|
|
add r12, 8 ; pop value
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-25 22:37:04 +01:00
|
|
|
# : strlen ( addr -- len )
|
|
|
|
|
# for null terminated strings
|
|
|
|
|
|
|
|
|
|
:asm strlen {
|
|
|
|
|
mov rsi, [r12] ; address
|
|
|
|
|
xor rcx, rcx ; length counter
|
|
|
|
|
.strlen_loop:
|
|
|
|
|
mov al, [rsi]
|
|
|
|
|
test al, al
|
|
|
|
|
jz .strlen_done
|
|
|
|
|
inc rcx
|
|
|
|
|
inc rsi
|
|
|
|
|
jmp .strlen_loop
|
|
|
|
|
.strlen_done:
|
|
|
|
|
mov rax, rcx
|
|
|
|
|
mov [r12], rax ; store length on stack
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : argc ( -- n )
|
|
|
|
|
:asm argc {
|
|
|
|
|
extern argc
|
|
|
|
|
mov rax, [rel argc]
|
|
|
|
|
sub r12, 8
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : argv ( -- ptr )
|
|
|
|
|
:asm argv {
|
|
|
|
|
extern argv
|
|
|
|
|
mov rax, [rel argv]
|
|
|
|
|
sub r12, 8
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : argv@ ( n -- ptr )
|
|
|
|
|
:asm argv@ {
|
|
|
|
|
extern argv
|
|
|
|
|
mov rbx, [r12] ; n
|
|
|
|
|
mov rax, [rel argv]
|
|
|
|
|
mov rax, [rax + rbx*8]
|
|
|
|
|
mov [r12], rax
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-18 11:32:35 +01:00
|
|
|
# : c@ ( addr -- byte )
|
|
|
|
|
:asm c@ {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get address from stack
|
|
|
|
|
movzx rax, byte [rax] ; load byte at address, zero-extend to rax
|
|
|
|
|
mov [r12], rax ; store result back on stack
|
2025-12-18 11:32:35 +01:00
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : c! ( byte addr -- )
|
|
|
|
|
:asm c! {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get address from stack
|
|
|
|
|
add r12, 8 ; pop address
|
|
|
|
|
mov rbx, [r12] ; get byte value
|
|
|
|
|
mov [rbx], al ; store byte at address
|
2025-12-18 11:32:35 +01:00
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : r@ ( -- x )
|
|
|
|
|
:asm r@ {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r13] ; get value from return stack
|
|
|
|
|
sub r12, 8 ; make room on data stack
|
|
|
|
|
mov [r12], rax ; push value to data stack
|
2025-12-18 11:32:35 +01:00
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : dup ( x -- x x )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm dup {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top of stack
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; duplicate value
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : drop ( x -- )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm drop {
|
2025-12-24 23:19:08 +01:00
|
|
|
add r12, 8 ; remove top of stack
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : over ( x1 x2 -- x1 x2 x1 )
|
2025-12-11 20:07:10 +01:00
|
|
|
:asm over {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12 + 8] ; get second item
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; push copy
|
2025-12-11 20:07:10 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : swap ( x1 x2 -- x2 x1 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm swap {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
mov rbx, [r12 + 8] ; get second
|
|
|
|
|
mov [r12], rbx ; swap
|
2025-12-06 16:30:58 +01:00
|
|
|
mov [r12 + 8], rax
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : rot ( x1 x2 x3 -- x2 x3 x1 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm rot {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; x3 (top)
|
|
|
|
|
mov rbx, [r12 + 8] ; x2
|
|
|
|
|
mov rcx, [r12 + 16] ; x1 (bottom)
|
|
|
|
|
mov [r12], rcx ; new top = x1
|
|
|
|
|
mov [r12 + 8], rax ; new 2nd = x3
|
|
|
|
|
mov [r12 + 16], rbx ; new 3rd = x2
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : -rot ( x1 x2 x3 -- x3 x1 x2 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm -rot {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; x3 (top)
|
|
|
|
|
mov rbx, [r12 + 8] ; x2
|
|
|
|
|
mov rcx, [r12 + 16] ; x1 (bottom)
|
|
|
|
|
mov [r12], rbx ; new top = x2
|
|
|
|
|
mov [r12 + 8], rcx ; new 2nd = x1
|
|
|
|
|
mov [r12 + 16], rax ; new 3rd = x3
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : nip ( x1 x2 -- x2 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm nip {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; drop lower
|
|
|
|
|
mov [r12], rax ; keep original top
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : tuck ( x1 x2 -- x2 x1 x2 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm tuck {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; x2 (top)
|
|
|
|
|
mov rbx, [r12 + 8] ; x1
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; x2
|
|
|
|
|
mov [r12 + 8], rbx ; x1
|
|
|
|
|
mov [r12 + 16], rax ; x2
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : 2dup ( x1 x2 -- x1 x2 x1 x2 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm 2dup {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; b (top)
|
|
|
|
|
mov rbx, [r12 + 8] ; a
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rbx ; push a
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; push b
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : 2drop ( x1 x2 -- )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm 2drop {
|
2025-12-24 23:19:08 +01:00
|
|
|
add r12, 16 ; remove two items
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm 2swap {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; d (top)
|
|
|
|
|
mov rbx, [r12 + 8] ; c
|
|
|
|
|
mov rcx, [r12 + 16] ; b
|
|
|
|
|
mov rdx, [r12 + 24] ; a (bottom)
|
|
|
|
|
mov [r12], rcx ; new top = b
|
|
|
|
|
mov [r12 + 8], rdx ; new 2nd = a
|
|
|
|
|
mov [r12 + 16], rax ; new 3rd = d
|
|
|
|
|
mov [r12 + 24], rbx ; new 4th = c
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : 2over ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm 2over {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12 + 16] ; b
|
|
|
|
|
mov rbx, [r12 + 24] ; a
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rbx ; push a
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; push b
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : + ( x1 x2 -- x3 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm + {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
add qword [r12], rax ; add to next
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : - ( x1 x2 -- x3 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm - {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
sub qword [r12], rax ; subtract from next
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : * ( x1 x2 -- x3 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm * {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
imul qword [r12] ; multiply
|
|
|
|
|
mov [r12], rax ; store result
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : / ( x1 x2 -- x3 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm / {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rbx, [r12] ; divisor
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rax, [r12] ; dividend
|
|
|
|
|
cqo ; sign-extend
|
|
|
|
|
idiv rbx ; divide
|
|
|
|
|
mov [r12], rax ; store quotient
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : % ( x1 x2 -- x3 )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm % {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rbx, [r12] ; divisor
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rax, [r12] ; dividend
|
|
|
|
|
cqo ; sign-extend
|
|
|
|
|
idiv rbx ; divide
|
|
|
|
|
mov [r12], rdx ; store remainder
|
2025-12-06 16:30:58 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : == ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm == {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
sete bl ; set if equal
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : != ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm != {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
setne bl ; set if not equal
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : < ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm < {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
setl bl ; set if less
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : > ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm > {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
setg bl ; set if greater
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : <= ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm <= {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
setle bl ; set if less or equal
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : >= ( x1 x2 -- flag )
|
2025-12-06 18:30:29 +01:00
|
|
|
:asm >= {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
|
|
|
|
cmp rbx, rax ; compare
|
2025-12-06 18:30:29 +01:00
|
|
|
mov rbx, 0
|
2025-12-24 23:19:08 +01:00
|
|
|
setge bl ; set if greater or equal
|
|
|
|
|
mov [r12], rbx ; store flag
|
2025-12-06 18:30:29 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : @ ( addr -- x )
|
2025-12-06 17:24:30 +01:00
|
|
|
:asm @ {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get address
|
|
|
|
|
mov rax, [rax] ; load value
|
|
|
|
|
mov [r12], rax ; store on stack
|
2025-12-06 17:24:30 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : ! ( x addr -- )
|
2025-12-06 17:24:30 +01:00
|
|
|
:asm ! {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get address
|
|
|
|
|
add r12, 8 ; pop address
|
|
|
|
|
mov rbx, [r12] ; get value
|
|
|
|
|
mov [rax], rbx ; store value at address
|
|
|
|
|
add r12, 8 ; pop value
|
2025-12-06 17:24:30 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : mmap ( addr len prot flags fd offset -- addr )
|
2025-12-06 17:24:30 +01:00
|
|
|
:asm mmap {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov r9, [r12] ; offset
|
2025-12-23 23:27:17 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov r8, [r12] ; fd
|
2025-12-23 23:27:17 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov r10, [r12] ; flags
|
2025-12-23 23:27:17 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rdx, [r12] ; prot
|
2025-12-23 23:27:17 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rsi, [r12] ; len
|
2025-12-23 23:27:17 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rdi, [r12] ; addr
|
|
|
|
|
mov rax, 9 ; syscall: mmap
|
2025-12-23 23:27:17 +01:00
|
|
|
syscall
|
2025-12-25 21:30:11 +01:00
|
|
|
sub r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov [r12], rax ; return addr
|
2025-12-06 17:24:30 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : munmap ( addr len -- res )
|
2025-12-06 17:24:30 +01:00
|
|
|
:asm munmap {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rsi, [r12] ; len
|
2025-12-06 17:24:30 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rdi, [r12] ; addr
|
|
|
|
|
mov rax, 11 ; syscall: munmap
|
2025-12-06 17:24:30 +01:00
|
|
|
syscall
|
2025-12-25 21:30:11 +01:00
|
|
|
sub r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov [r12], rax ; return value
|
2025-12-06 17:24:30 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : exit ( code -- )
|
2025-12-06 16:30:58 +01:00
|
|
|
:asm exit {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rdi, [r12] ; exit code
|
2025-12-06 16:30:58 +01:00
|
|
|
add r12, 8
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, 60 ; syscall: exit
|
2025-12-06 16:30:58 +01:00
|
|
|
syscall
|
|
|
|
|
}
|
|
|
|
|
;
|
2025-12-08 18:14:52 +01:00
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : and ( x1 x2 -- flag )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm and {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
2025-12-14 00:38:19 +01:00
|
|
|
test rax, rax
|
|
|
|
|
setz cl
|
|
|
|
|
test rbx, rbx
|
|
|
|
|
setz dl
|
|
|
|
|
movzx rcx, cl
|
|
|
|
|
movzx rdx, dl
|
2025-12-24 23:19:08 +01:00
|
|
|
and rcx, rdx ; logical and
|
|
|
|
|
mov [r12], rcx ; store flag
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : or ( x1 x2 -- flag )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm or {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get top
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rbx, [r12] ; get next
|
2025-12-14 00:38:19 +01:00
|
|
|
test rax, rax
|
|
|
|
|
setz cl
|
|
|
|
|
test rbx, rbx
|
|
|
|
|
setz dl
|
|
|
|
|
movzx rcx, cl
|
|
|
|
|
movzx rdx, dl
|
2025-12-24 23:19:08 +01:00
|
|
|
or rcx, rdx ; logical or
|
|
|
|
|
mov [r12], rcx ; store flag
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : not ( x -- flag )
|
2025-12-14 00:38:19 +01:00
|
|
|
:asm not {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get value
|
2025-12-14 00:38:19 +01:00
|
|
|
test rax, rax
|
2025-12-24 23:19:08 +01:00
|
|
|
setz al ; set if zero
|
2025-12-14 00:38:19 +01:00
|
|
|
movzx rax, al
|
2025-12-24 23:19:08 +01:00
|
|
|
mov [r12], rax ; store flag
|
2025-12-14 00:38:19 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : >r ( x -- )
|
2025-12-08 18:14:52 +01:00
|
|
|
:asm >r {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r12] ; get value
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
sub r13, 8 ; make room on return stack
|
|
|
|
|
mov [r13], rax ; push to return stack
|
2025-12-08 18:14:52 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : r> ( -- x )
|
2025-12-08 18:14:52 +01:00
|
|
|
:asm r> {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rax, [r13] ; get value from return stack
|
|
|
|
|
add r13, 8 ; pop return stack
|
|
|
|
|
sub r12, 8 ; make room on data stack
|
|
|
|
|
mov [r12], rax ; push to data stack
|
2025-12-08 18:14:52 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : rdrop ( -- )
|
2025-12-08 18:14:52 +01:00
|
|
|
:asm rdrop {
|
2025-12-24 23:19:08 +01:00
|
|
|
add r13, 8 ; pop return stack
|
2025-12-08 18:14:52 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : pick ( n -- x )
|
2025-12-11 20:07:10 +01:00
|
|
|
:asm pick {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rcx, [r12] ; get index
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rax, [r12 + rcx * 8] ; get value at index
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; push value
|
2025-12-11 20:07:10 +01:00
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
2025-12-24 23:19:08 +01:00
|
|
|
# : rpick ( n -- x )
|
2025-12-08 18:14:52 +01:00
|
|
|
:asm rpick {
|
2025-12-24 23:19:08 +01:00
|
|
|
mov rcx, [r12] ; get index
|
|
|
|
|
add r12, 8 ; pop
|
|
|
|
|
mov rax, [r13 + rcx * 8] ; get value from return stack
|
|
|
|
|
sub r12, 8 ; make room
|
|
|
|
|
mov [r12], rax ; push value
|
2025-12-08 18:14:52 +01:00
|
|
|
}
|
|
|
|
|
;
|
2025-12-25 12:20:11 +01:00
|
|
|
|
|
|
|
|
# : neg ( x -- -x )
|
|
|
|
|
:asm neg {
|
|
|
|
|
mov rax, [r12] ; get value
|
|
|
|
|
neg rax ; arithmetic negation
|
|
|
|
|
mov [r12], rax ; store result
|
|
|
|
|
}
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# : bitnot ( 0|1 -- 1|0 )
|
|
|
|
|
:asm bitnot {
|
|
|
|
|
mov rax, [r12] ; get value
|
|
|
|
|
xor rax, 1 ; flip lowest bit
|
|
|
|
|
mov [r12], rax ; store result
|
|
|
|
|
}
|
|
|
|
|
;
|