2021-11-19 09:52:27 -05:00
|
|
|
; declaration:
|
2022-01-06 11:57:55 -05:00
|
|
|
; global <name>
|
|
|
|
; local <name>
|
|
|
|
; argument <name>
|
2021-11-19 09:52:27 -05:00
|
|
|
; :<label>
|
|
|
|
; statement:
|
|
|
|
; <declaration>
|
|
|
|
; if <term> <==/</>/>=/<=/!=> <term> goto <label> NOTE: this uses signed comparisons
|
|
|
|
; goto <label>
|
|
|
|
; <lvalue> = <rvalue>
|
|
|
|
; <lvalue> += <rvalue>
|
|
|
|
; <lvalue> -= <rvalue>
|
|
|
|
; <function>(<term>, <term>, ...)
|
|
|
|
; return <rvalue>
|
2022-01-05 23:44:04 -05:00
|
|
|
; string <str>
|
2021-11-19 09:52:27 -05:00
|
|
|
; byte <number>
|
|
|
|
; term:
|
|
|
|
; <var>
|
2022-01-06 11:57:55 -05:00
|
|
|
; .<label>
|
2021-11-19 09:52:27 -05:00
|
|
|
; <number>
|
|
|
|
; number:
|
|
|
|
; 'c
|
|
|
|
; 12345
|
|
|
|
; 0xabc
|
|
|
|
; lvalue:
|
|
|
|
; <var>
|
2022-01-06 11:57:55 -05:00
|
|
|
; *1<var> / *2<var> / *4<var> / *8<var>
|
2021-11-19 09:52:27 -05:00
|
|
|
; rvalue:
|
2022-01-06 11:57:55 -05:00
|
|
|
; <term>
|
2021-11-19 09:52:27 -05:00
|
|
|
; &<var>
|
2022-01-06 11:57:55 -05:00
|
|
|
; *1<var> / *2<var> / *4<var> / *8<var>
|
|
|
|
; ~<term>
|
2021-11-19 09:52:27 -05:00
|
|
|
; <function>(<term>, <term>, ...)
|
|
|
|
; <term> + <term>
|
|
|
|
; <term> - <term>
|
|
|
|
; NOTE: *, /, % are signed (imul and idiv)
|
|
|
|
; <term> * <term>
|
|
|
|
; <term> / <term>
|
|
|
|
; <term> % <term>
|
|
|
|
; <term> & <term>
|
|
|
|
; <term> | <term>
|
|
|
|
; <term> ^ <term>
|
|
|
|
; <term> < <term> (left shift)
|
|
|
|
; <term> > <term> (unsigned right shift)
|
|
|
|
|
2022-01-06 13:53:52 -05:00
|
|
|
syscall(1, 1, .str_hw, 14)
|
|
|
|
syscall(0x3c, 42)
|
|
|
|
|
|
|
|
:str_hw
|
2022-01-06 14:02:30 -05:00
|
|
|
string Hello, world!
|
2022-01-06 13:53:52 -05:00
|
|
|
byte 10
|
|
|
|
|
2022-01-06 14:02:30 -05:00
|
|
|
|
|
|
|
|
2022-01-06 13:53:52 -05:00
|
|
|
:syscall
|
|
|
|
function
|
|
|
|
; I've done some testing, and this should be okay even if
|
|
|
|
; rbp-56 goes beyond the end of the stack.
|
|
|
|
; mov rax, [rbp-16]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xf0
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov rdi, rax
|
|
|
|
byte 0x48
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc7
|
|
|
|
|
|
|
|
; mov rax, [rbp-24]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xe8
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov rsi, rax
|
|
|
|
byte 0x48
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc6
|
|
|
|
|
|
|
|
; mov rax, [rbp-32]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xe0
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov rdx, rax
|
|
|
|
byte 0x48
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc2
|
|
|
|
|
|
|
|
; mov rax, [rbp-40]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xd8
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov r10, rax
|
|
|
|
byte 0x49
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc2
|
|
|
|
|
|
|
|
; mov rax, [rbp-48]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xd0
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov r8, rax
|
|
|
|
byte 0x49
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc0
|
|
|
|
|
|
|
|
; mov rax, [rbp-56]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xc8
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
; mov r9, rax
|
|
|
|
byte 0x49
|
|
|
|
byte 0x89
|
|
|
|
byte 0xc1
|
|
|
|
|
|
|
|
; mov rax, [rbp-8]
|
|
|
|
byte 0x48
|
|
|
|
byte 0x8b
|
|
|
|
byte 0x85
|
|
|
|
byte 0xf8
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
byte 0xff
|
|
|
|
|
|
|
|
; syscall
|
|
|
|
byte 0x0f
|
|
|
|
byte 0x05
|
|
|
|
|
|
|
|
return
|
|
|
|
|
2022-01-05 18:19:28 -05:00
|
|
|
global x
|
|
|
|
global y ;123
|
|
|
|
global z
|
2022-01-06 11:57:55 -05:00
|
|
|
:test
|
|
|
|
function
|
|
|
|
local eee
|
|
|
|
local fff
|
|
|
|
local ggg
|
2022-01-06 13:13:12 -05:00
|
|
|
return test2(eee, 0x223, ggg)
|
|
|
|
|
2022-01-06 11:57:55 -05:00
|
|
|
:test2
|
|
|
|
function
|
|
|
|
return -123
|
|
|
|
|
2022-01-05 23:44:04 -05:00
|
|
|
|
2021-11-19 23:27:08 -05:00
|
|
|
:strlen
|
|
|
|
function
|
2022-01-05 18:19:28 -05:00
|
|
|
argument s
|
|
|
|
local len
|
|
|
|
local c
|
|
|
|
local p
|
2021-11-19 09:52:27 -05:00
|
|
|
len = 0
|
2021-11-19 23:27:08 -05:00
|
|
|
:strlen_loop
|
2022-01-05 18:19:28 -05:00
|
|
|
p = s + len
|
|
|
|
c = *1 p
|
2021-11-19 23:27:08 -05:00
|
|
|
if c == 0 goto strlen_loop_end
|
2021-11-19 09:52:27 -05:00
|
|
|
len += 1
|
2021-11-19 23:27:08 -05:00
|
|
|
goto strlen_loop
|
|
|
|
:strlen_loop_end
|
2021-11-19 09:52:27 -05:00
|
|
|
return len
|
|
|
|
|
2021-11-19 23:27:08 -05:00
|
|
|
:putc
|
|
|
|
function
|
2022-01-05 18:19:28 -05:00
|
|
|
argument c
|
|
|
|
local p
|
2021-11-19 09:52:27 -05:00
|
|
|
p = &c
|
2022-01-05 23:44:04 -05:00
|
|
|
syscall(1, 1, p, 1)
|
2021-11-19 09:52:27 -05:00
|
|
|
return
|
2021-11-20 11:38:34 -05:00
|
|
|
|
2021-11-19 23:27:08 -05:00
|
|
|
:puts
|
|
|
|
function
|
2022-01-05 18:19:28 -05:00
|
|
|
argument s
|
|
|
|
local len
|
2021-11-19 09:52:27 -05:00
|
|
|
len = strlen(s)
|
2022-01-05 23:44:04 -05:00
|
|
|
syscall(1, 1, s, len)
|
2021-11-19 09:52:27 -05:00
|
|
|
return
|
|
|
|
|
2021-11-19 23:27:08 -05:00
|
|
|
:main
|
|
|
|
function
|
2022-01-06 13:13:12 -05:00
|
|
|
puts(.str_hello_world)
|
2022-01-05 23:44:04 -05:00
|
|
|
syscall(0x3c, 0)
|
|
|
|
:str_hello_world
|
|
|
|
string Hello, world!
|
|
|
|
byte 10
|
|
|
|
byte 0
|
2021-11-19 23:27:08 -05:00
|
|
|
|
|
|
|
:f
|
|
|
|
function
|
2022-01-05 18:19:28 -05:00
|
|
|
argument x
|
|
|
|
argument y
|
|
|
|
local v
|
|
|
|
local p
|
|
|
|
v = *4x
|
|
|
|
p = *8y
|
|
|
|
*4p = v
|
2021-11-19 09:52:27 -05:00
|
|
|
if v == 0 goto something
|
2022-01-05 18:19:28 -05:00
|
|
|
*1p = v + 1
|
2022-01-05 23:44:04 -05:00
|
|
|
v = *2p
|
|
|
|
return v
|
2021-11-19 09:52:27 -05:00
|
|
|
:something
|
2022-01-05 23:44:04 -05:00
|
|
|
v = *4p
|
|
|
|
return v
|