summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--04b/in0382
-rw-r--r--04b/in04b122
-rw-r--r--instructions.txt6
3 files changed, 188 insertions, 22 deletions
diff --git a/04b/in03 b/04b/in03
index f03c08a..b07874d 100644
--- a/04b/in03
+++ b/04b/in03
@@ -133,6 +133,13 @@ call :string=
D=A
?D!0:handle_return
+I=:line
+J=:"byte"
+C=x20
+call :string=
+D=A
+?D!0:handle_byte
+
; set delimiter to newline
C=xa
@@ -142,6 +149,12 @@ call :string=
D=A
?D!0:handle_function
+I=:line
+J=:"return\n"
+call :string=
+D=A
+?D!0:handle_return
+
; check if this is a function call (where we discard the return value)
I=:line
; (check for an opening bracket not preceded by a space)
@@ -195,6 +208,25 @@ align
:local_variable_name
reserve d8
+:handle_byte
+ I=:line
+ ; 5 = length of "byte "
+ I+=d5
+ call :read_number
+ ; make sure byte is 0-255
+ C=A
+ D=xff
+ ?CaD:bad_byte
+ ; write byte
+ I=:byte
+ 1I=C
+ J=d4
+ D=d1
+ syscall x1
+ !:read_line
+:byte
+ reserve d1
+
:handle_call
J=I
; just use the rvalue function call code
@@ -420,11 +452,18 @@ align
:handle_return
I=:line
- ; "return " is 7 chars long
- I+=d7
+ ; skip "return"
+ I+=d6
+ C=1I
+ D=xa
+ ?C=D:no_return_value
+
+ ; skip ' ' after return
+ I+=d1
call :set_rax_to_rvalue
+ :no_return_value
J=d4
I=:function_epilogue
D=d15
@@ -520,7 +559,7 @@ align
C=1I
D=''
- ?C=D:term_char
+ ?C=D:term_number
D='.
?C=D:term_label
D=d58
@@ -952,12 +991,7 @@ align
; put address in rax
I=C
!:set_rax_to_immediate
-
-:term_char
- I+=d1
- I=1I
- !:set_rax_to_immediate
-
+
:number_is_negative
reserve d1
@@ -969,6 +1003,8 @@ align
; set rax to the number in the string at rsi
:read_number
C=1I
+ D=''
+ ?C=D:read_char
D='-
; set rdx to 0 if number is positive, 1 if negative
?C=D:read_number_negative
@@ -981,7 +1017,7 @@ align
; store away negativity
C=:number_is_negative
1C=D
-
+ ; check if number starts with 0-9
C=1I
D='9
?C>D:bad_number
@@ -1011,6 +1047,12 @@ align
:decimal_number_loop_end
!:read_number_output
+:read_char
+ I+=d1
+ R=1I
+ I+=d1
+ !:read_number_output
+
:number_starting_with0
I+=d1
C=1I
@@ -1018,12 +1060,9 @@ align
?C=D:read_hex_number
; otherwise, it should just be 0
R=d0
- !:read_number_output
-
+ !:read_number_output
:read_hex_number
- ; 0 followed by something other than x
- ?C!D:bad_number
I+=d1
; rbp will store the number
R=d0
@@ -1283,6 +1322,15 @@ align
xa
x0
+:bad_byte
+ B=:bad_byte_error_message
+ !:program_error
+
+:bad_byte_error_message
+ str Byte not in range 0-255.
+ xa
+ x0
+
:bad_number
B=:bad_number_error_message
!:program_error
@@ -1532,6 +1580,12 @@ align
:"return"
str return
x20
+:"return\n"
+ str return
+ xa
+:"byte"
+ str byte
+ x20
:"function"
str function
xa
diff --git a/04b/in04b b/04b/in04b
index c9a471b..c64aecd 100644
--- a/04b/in04b
+++ b/04b/in04b
@@ -43,8 +43,123 @@
; <term> < <term> (left shift)
; <term> > <term> (unsigned right shift)
-main(46) ; hello
+syscall(1, 1, .str_hw, 14)
+syscall(0x3c, 42)
+
+:str_hw
+ byte 'H
+ byte 'e
+ byte 'l
+ byte 'l
+ byte 'o
+ byte ',
+ byte 32
+ byte 'w
+ byte 'o
+ byte 'r
+ byte 'l
+ byte 'd
+ byte '!
+ byte 10
+
+: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
+
global x
global y ;123
global z
@@ -59,11 +174,6 @@ function
function
return -123
-:syscall
-function
- ; ...
- byte 0x0f
- byte 0x05
:strlen
function
diff --git a/instructions.txt b/instructions.txt
index 038c6ab..03b13cf 100644
--- a/instructions.txt
+++ b/instructions.txt
@@ -40,9 +40,11 @@ mov byte [rbx], al
mov al, byte [rbx]
>8a 03
mov rax, qword [rbp+imm32]
->48 8b 85 IMM32 (note: imm may be negative)
+>48 8b 85 IMM32 (note: imm may be negative)
+lea rax, [rbp+imm32]
+>48 8d 85 IMM32 (note: imm may be negative)
mov qword [rbp+imm32], rax
->48 89 85 IMM32 (note: imm may be negative)
+>48 89 85 IMM32 (note: imm may be negative)
mov qword [rsp+imm32], rax
>48 89 84 24 IMM32 (note: imm may be negative)
mov qword [rsp], rbp