fix function prologue/epilogue, 2nd pass
This commit is contained in:
parent
4b9596e892
commit
d03916a3f8
2 changed files with 210 additions and 25 deletions
213
04b/in03
213
04b/in03
|
@ -34,6 +34,7 @@ A=d3
|
|||
J=A
|
||||
?J<0:output_file_error
|
||||
|
||||
:second_pass_starting_point
|
||||
; write ELF header
|
||||
J=d4
|
||||
I=:ELF_header
|
||||
|
@ -150,6 +151,24 @@ D=A
|
|||
!:read_line
|
||||
|
||||
:eof
|
||||
C=:second_pass
|
||||
D=1C
|
||||
?D!0:exit_success
|
||||
; set 2nd pass to 1
|
||||
1C=d1
|
||||
; seek both files back to start
|
||||
J=d3
|
||||
I=d0
|
||||
D=d0
|
||||
syscall x8
|
||||
J=d4
|
||||
I=d0
|
||||
D=d0
|
||||
syscall x8
|
||||
|
||||
!:second_pass_starting_point
|
||||
|
||||
:exit_success
|
||||
J=d0
|
||||
syscall x3c
|
||||
|
||||
|
@ -177,7 +196,7 @@ align
|
|||
C=:local_start
|
||||
8C=I
|
||||
J=:local_variables
|
||||
D=d9
|
||||
D=d5
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C!0:local_redeclaration
|
||||
|
@ -192,9 +211,9 @@ align
|
|||
J+=d1
|
||||
; store address
|
||||
D=:stack_end
|
||||
D=8D
|
||||
8J=D
|
||||
J+=d8
|
||||
D=4D
|
||||
4J=D
|
||||
J+=d4
|
||||
; store null terminator
|
||||
1J=0
|
||||
; update :stack_end
|
||||
|
@ -222,6 +241,11 @@ align
|
|||
reserve d8
|
||||
|
||||
:handle_global
|
||||
; ignore if this is the second pass
|
||||
C=:second_pass
|
||||
C=1C
|
||||
?C!0:read_line
|
||||
|
||||
; skip ' '
|
||||
I+=d1
|
||||
call :read_type
|
||||
|
@ -234,7 +258,7 @@ align
|
|||
C=:global_start
|
||||
8C=I
|
||||
J=:global_variables
|
||||
D=d9
|
||||
D=d5
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C!0:global_redeclaration
|
||||
|
@ -250,9 +274,9 @@ align
|
|||
J+=d1
|
||||
; store address
|
||||
D=:static_memory_end
|
||||
D=8D
|
||||
8J=D
|
||||
J+=d8
|
||||
D=4D
|
||||
4J=D
|
||||
J+=d4
|
||||
; store null terminator
|
||||
1J=0
|
||||
; update :static_memory_end
|
||||
|
@ -267,10 +291,10 @@ align
|
|||
!:read_line
|
||||
|
||||
:handle_function
|
||||
; emit "mov rbp, rsp"
|
||||
; emit prologue
|
||||
J=d4
|
||||
I=:mov_rbp_rsp
|
||||
D=d3
|
||||
I=:function_prologue
|
||||
D=d14
|
||||
syscall x1
|
||||
|
||||
; reset local variable table
|
||||
|
@ -282,10 +306,50 @@ align
|
|||
; go read the next line
|
||||
!:read_line
|
||||
|
||||
:mov_rbp_rsp
|
||||
:function_prologue
|
||||
; sub rsp, 8
|
||||
x48
|
||||
x81
|
||||
xec
|
||||
x08
|
||||
x00
|
||||
x00
|
||||
x00
|
||||
; mov [rsp], rbp
|
||||
x48
|
||||
x89
|
||||
x2c
|
||||
x24
|
||||
; mov rbp, rsp
|
||||
R=S
|
||||
; total length: 7 + 4 + 3 = 14 bytes
|
||||
|
||||
:function_epilogue
|
||||
; mov rsp, rbp
|
||||
S=R
|
||||
; mov rbp, [rsp]
|
||||
x48
|
||||
x8b
|
||||
x2c
|
||||
x24
|
||||
; add rsp, 8
|
||||
x48
|
||||
x81
|
||||
xc4
|
||||
x08
|
||||
x00
|
||||
x00
|
||||
x00
|
||||
; ret
|
||||
return
|
||||
; total length = 15 bytes
|
||||
|
||||
:handle_label_definition
|
||||
; ignore if this is the second pass
|
||||
C=:second_pass
|
||||
C=1C
|
||||
?C!0:read_line
|
||||
|
||||
; make sure label only has identifier characters
|
||||
I=:line
|
||||
I+=d1
|
||||
|
@ -338,16 +402,9 @@ align
|
|||
; @TODO: handle argument
|
||||
|
||||
|
||||
; emit "mov rsp, rbp"
|
||||
J=d4
|
||||
I=:mov_rsp_rbp
|
||||
D=d3
|
||||
syscall x1
|
||||
|
||||
; emit "ret"
|
||||
J=d4
|
||||
I=:ret
|
||||
D=d1
|
||||
I=:function_epilogue
|
||||
D=d15
|
||||
syscall x1
|
||||
|
||||
; go read the next lines
|
||||
|
@ -391,6 +448,11 @@ align
|
|||
; look up identifier rsi in list rdi with separation rdx between entries
|
||||
; returns address of whatever's right after the identifier in the list, or 0 if not found
|
||||
:ident_lookup
|
||||
C=:second_pass
|
||||
C=1C
|
||||
; use default of 0 on first pass
|
||||
?C!0:return_0
|
||||
|
||||
C=:ident_lookup_sep
|
||||
8C=D
|
||||
C=:ident_lookup_i
|
||||
|
@ -432,6 +494,104 @@ align
|
|||
?B=A:return_1
|
||||
!:return_0
|
||||
|
||||
; set rax to the term in rsi
|
||||
:set_rax_to_term
|
||||
R=I
|
||||
|
||||
C=1I
|
||||
D=''
|
||||
?C=D:term_char
|
||||
|
||||
C=1I
|
||||
D=d58
|
||||
?C<D:term_number
|
||||
|
||||
; variable
|
||||
J=:local_variables
|
||||
D=d5
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:rax2term_try_global
|
||||
; it's a local variable
|
||||
; skip over its type
|
||||
C+=d1
|
||||
; read the offset from rbp
|
||||
D=4C
|
||||
; put negated offset in rcx
|
||||
C=d0
|
||||
C-=D
|
||||
; store negated offset in :rax2term_addr
|
||||
D=:rax2term_addr
|
||||
4D=C
|
||||
|
||||
J=d4
|
||||
I=:load_rbp_offset_prefix
|
||||
D=d3
|
||||
syscall x1
|
||||
J=d4
|
||||
I=:rax2term_addr
|
||||
D=d4
|
||||
syscall x1
|
||||
|
||||
|
||||
:rax2term_try_global
|
||||
J=:global_variables
|
||||
D=d5
|
||||
call :ident_lookup
|
||||
C=A
|
||||
?C=0:bad_term
|
||||
; it's a global variable
|
||||
; skip over its type
|
||||
C+=d1
|
||||
C=4C
|
||||
D=:rax2term_addr
|
||||
4D=C
|
||||
|
||||
; put address in rbx
|
||||
J=d4
|
||||
I=:mov_ebx_imm32_prefix
|
||||
D=d1
|
||||
syscall x1
|
||||
J=d4
|
||||
I=:rax2term_addr
|
||||
D=d4
|
||||
syscall x1
|
||||
|
||||
; now load [rbx] into rax
|
||||
J=d4
|
||||
I=:mov_rax_[rbx]
|
||||
D=d3
|
||||
syscall x1
|
||||
|
||||
return
|
||||
|
||||
:term_char
|
||||
; @TODO
|
||||
xcc
|
||||
|
||||
:term_number
|
||||
; @TODO
|
||||
xcc
|
||||
|
||||
align
|
||||
:rax2term_addr
|
||||
reserve d4
|
||||
|
||||
:mov_ebx_imm32_prefix
|
||||
xbb
|
||||
|
||||
:mov_rax_[rbx]
|
||||
x48
|
||||
x8b
|
||||
x03
|
||||
|
||||
; prefix for mov rax, [rbp+IMM32]
|
||||
:load_rbp_offset_prefix
|
||||
x48
|
||||
x8b
|
||||
x85
|
||||
|
||||
|
||||
; read the space-terminated type from rsi, advance rsi, and set rax to the corresponding type number:
|
||||
; 0 for non-pointer types
|
||||
; 1 for pointer to char
|
||||
|
@ -532,6 +692,15 @@ align
|
|||
xa
|
||||
x0
|
||||
|
||||
:bad_term
|
||||
B=:bad_term_error_message
|
||||
!:program_error
|
||||
|
||||
:bad_term_error_message
|
||||
str Bad term.
|
||||
xa
|
||||
x0
|
||||
|
||||
:label_redefinition
|
||||
B=:label_redefinition_error_message
|
||||
!:program_error
|
||||
|
@ -796,6 +965,8 @@ align
|
|||
reserve d20000
|
||||
:labels
|
||||
reserve d200000
|
||||
:second_pass
|
||||
reserve d1
|
||||
|
||||
:ELF_header
|
||||
x7f
|
||||
|
|
|
@ -37,10 +37,16 @@ mov byte [rbx], al
|
|||
>88 03
|
||||
mov al, byte [rbx]
|
||||
>8a 03
|
||||
mov qword [rsp], rax
|
||||
>48 89 04 24
|
||||
mov rax, qword [rsp]
|
||||
>48 8b 04 24
|
||||
mov rax, qword [rbp+imm32]
|
||||
>48 8b 85 IMM32 (note: imm may be negative)
|
||||
mov qword [rbp+imm32], rax
|
||||
>48 89 85 IMM32 (note: imm may be negative)
|
||||
mov qword [rsp], rbp
|
||||
>48 89 2c 24
|
||||
mov rbp, qword [rsp]
|
||||
>48 8b 2c 24
|
||||
mov ebx, imm32
|
||||
>bb IMM32
|
||||
neg rax
|
||||
>48 f7 d8
|
||||
add rax, rbx
|
||||
|
@ -75,6 +81,8 @@ sar rax, imm8
|
|||
>48 c1 f8 IMM8
|
||||
sub rsp, imm32
|
||||
>48 81 ec IMM32
|
||||
add rsp, imm32
|
||||
>48 81 c4 IMM32
|
||||
cmp rax, rbx
|
||||
>48 39 d8
|
||||
test rax, rax
|
||||
|
@ -102,3 +110,9 @@ syscall
|
|||
nop
|
||||
>90
|
||||
(more will be added as needed)
|
||||
|
||||
to be removed:
|
||||
mov qword [rsp], rax
|
||||
>48 89 04 24
|
||||
mov rax, qword [rsp]
|
||||
>48 8b 04 24
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue