2023-08-20 04:02:24 +00:00
|
|
|
;© 2023 John Breaux
|
|
|
|
; examples of valid assembly
|
|
|
|
;
|
|
|
|
|
0.2.0: Feature update and Refactor
- Each major module (lexer, parser, assembler) has its own error type
- These error types are somewhat interconnected, but their
dependency relationships are one-way and well defined
- The AST is no longer responsible for assembling itself
- The Assembler (assembler::Assembler) will now visit every AST node
and accumulate words
- Words are assumed to be little-endian.
- There are now a set of assembler directives that affect the
generated output:
- .word <Number>: inserts a single word in the output
- .words [<Number>,*]: inserts multiple words in the output
- .byte <Number>: Alias for .word
- .bytes [<Number>,*]: Alias for .words
- .string "String": inserts a null-terminated UTF-8 encoded string
- .strings ["String",*]: "" multiple strings
- Data is always word-aligned at the moment.
- There are now assembler directives that affect the AST during
parsing:
- .include "path/to/file": Parses the contents of a file directly
into the AST
- Included files have their own defines, but *share* labels.
This is because .defines are a tokenizer construct, and
including a file creates a new buffer and tokenizer.
- Circular includes are NOT checked for at the moment.
It is very easy to exhaust the stack.
- General cleanup of several functions, comments, TODOs, etc.
- main.rs was moved to make room for upcoming improvements to the UI
TODO:
- REPL mode is only partially compatible with .define directive
- Branching to a label will branch to the data AT the label,
not the label itself. I doubt this is correct behavior.
- In case br <label> is meant to use the absolute address,
I've created a .org directive (currently unimplemented)
for specifying the load address of the program.
2023-09-05 06:54:50 +00:00
|
|
|
; testing labels
|
|
|
|
jmp main
|
|
|
|
|
|
|
|
; testing directives
|
|
|
|
.string "ABA"
|
|
|
|
.string "ABAB"
|
|
|
|
.word 0b0101101001011010
|
|
|
|
.words [dead beef]
|
|
|
|
|
|
|
|
main:
|
2023-08-25 08:01:53 +00:00
|
|
|
; testing defines
|
|
|
|
.define asdfgh #1000
|
|
|
|
.define qwerty @sp+
|
|
|
|
br asdfgh
|
|
|
|
mov qwerty, r15
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-20 04:02:24 +00:00
|
|
|
_register_mode:
|
|
|
|
.define numbered r1
|
|
|
|
mov r0, r1
|
|
|
|
mov r1, r2
|
|
|
|
mov r2, r3
|
|
|
|
mov r3, r4
|
|
|
|
mov r4, r5
|
|
|
|
mov r5, r6
|
|
|
|
mov r6, r7
|
|
|
|
mov r7, r8
|
|
|
|
mov r8, r9
|
|
|
|
mov r9, r10
|
|
|
|
mov r10, r11
|
|
|
|
mov r11, r12
|
|
|
|
mov r12, r13
|
|
|
|
mov r13, r14
|
|
|
|
mov r14, r15
|
|
|
|
|
|
|
|
.define special r2
|
|
|
|
mov pc, r15
|
|
|
|
mov sp, r15
|
|
|
|
mov sr, r15
|
|
|
|
mov cg, r15
|
|
|
|
|
|
|
|
|
|
|
|
indirect_mode:
|
|
|
|
.define numbered r3
|
|
|
|
mov @r0, r1
|
|
|
|
mov @r1, r2
|
|
|
|
;mov @r2, r3
|
|
|
|
;mov @r3, r4
|
|
|
|
mov @r4, r5
|
|
|
|
mov @r5, r6
|
|
|
|
mov @r6, r7
|
|
|
|
mov @r7, r8
|
|
|
|
mov @r8, r9
|
|
|
|
mov @r9, r10
|
|
|
|
mov @r10, r11
|
|
|
|
mov @r11, r12
|
|
|
|
mov @r12, r13
|
|
|
|
mov @r13, r14
|
|
|
|
mov @r14, r15
|
|
|
|
|
|
|
|
.define special r4
|
|
|
|
mov @pc, r15
|
|
|
|
mov @sp, r15
|
|
|
|
;mov @sr, r15 ; These are part of encodings for #immediate values [-1, 0, 1, 2, 4, 8]
|
|
|
|
;mov @cg, r15
|
|
|
|
|
|
|
|
indirect_pi_mode:
|
|
|
|
.define numbered r5
|
|
|
|
;mov @r0+, r1
|
|
|
|
mov @r1+, r2
|
|
|
|
;mov @r2+, r3
|
|
|
|
;mov @r3+, r4
|
|
|
|
mov @r4+, r5
|
|
|
|
mov @r5+, r6
|
|
|
|
mov @r6+, r7
|
|
|
|
mov @r7+, r8
|
|
|
|
mov @r8+, r9
|
|
|
|
mov @r9+, r10
|
|
|
|
mov @r10+, r11
|
|
|
|
mov @r11+, r12
|
|
|
|
mov @r12+, r13
|
|
|
|
mov @r13+, r14
|
|
|
|
mov @r14+, r15
|
|
|
|
|
|
|
|
.define special r6
|
|
|
|
;mov @pc+, r15 ; This is how mov-immediate is encoded, and is not valid
|
|
|
|
;mov @sp+, r15 ; pop r15
|
|
|
|
;mov @sr+, r15 ; These are part of encodings for #immediate values [-1, 0, 1, 2, 4, 8]
|
|
|
|
;mov @cg+, r15
|
|
|
|
|
|
|
|
indexed_mode:
|
|
|
|
.define numbered r7
|
|
|
|
mov.b 10(r0), r1
|
|
|
|
mov 10(r1), r2
|
|
|
|
;mov 10(r2), r3 ; Invalid: cannot index relative to sr
|
|
|
|
;mov 10(r3), r4 ; Invalid: cannot index relative to cg
|
|
|
|
mov 10(r4), r5
|
|
|
|
mov 10(r5), r6
|
|
|
|
mov 10(r6), r7
|
|
|
|
mov 10(r7), r8
|
|
|
|
mov 10(r8), r9
|
|
|
|
mov 10(r9), r10
|
|
|
|
mov 10(r10), r11
|
|
|
|
mov 10(r11), r12
|
|
|
|
mov 10(r12), r13
|
|
|
|
mov 10(r13), r14
|
|
|
|
mov 10(r14), r15
|
|
|
|
|
|
|
|
.define special r8
|
|
|
|
mov 10(pc), r15
|
|
|
|
mov 10(sp), r15
|
|
|
|
;mov 10(sr), r15 ; These are part of encodings for #immediate values [-1, 0, 1, 2, 4, 8]
|
|
|
|
;mov 10(cg), r15
|
|
|
|
|
|
|
|
_immediate_mode:
|
|
|
|
.define numbered r9
|
|
|
|
mov #beef, r0
|
|
|
|
mov #beef, r1
|
|
|
|
mov #beef, r2
|
|
|
|
mov #beef, r3
|
|
|
|
mov #beef, r4
|
|
|
|
mov #beef, r5
|
|
|
|
mov #beef, r6
|
|
|
|
mov #beef, r7
|
|
|
|
mov #beef, r8
|
|
|
|
mov #beef, r9
|
|
|
|
mov #beef, r10
|
|
|
|
mov #beef, r11
|
|
|
|
mov #beef, r12
|
|
|
|
mov #beef, r13
|
|
|
|
mov #beef, r14
|
|
|
|
mov #beef, r15
|
|
|
|
|
|
|
|
.define special r10
|
|
|
|
mov #beef, pc
|
|
|
|
mov #beef, sp
|
|
|
|
mov #beef, sr
|
|
|
|
mov #beef, cg
|
|
|
|
|
0.2.0: Feature update and Refactor
- Each major module (lexer, parser, assembler) has its own error type
- These error types are somewhat interconnected, but their
dependency relationships are one-way and well defined
- The AST is no longer responsible for assembling itself
- The Assembler (assembler::Assembler) will now visit every AST node
and accumulate words
- Words are assumed to be little-endian.
- There are now a set of assembler directives that affect the
generated output:
- .word <Number>: inserts a single word in the output
- .words [<Number>,*]: inserts multiple words in the output
- .byte <Number>: Alias for .word
- .bytes [<Number>,*]: Alias for .words
- .string "String": inserts a null-terminated UTF-8 encoded string
- .strings ["String",*]: "" multiple strings
- Data is always word-aligned at the moment.
- There are now assembler directives that affect the AST during
parsing:
- .include "path/to/file": Parses the contents of a file directly
into the AST
- Included files have their own defines, but *share* labels.
This is because .defines are a tokenizer construct, and
including a file creates a new buffer and tokenizer.
- Circular includes are NOT checked for at the moment.
It is very easy to exhaust the stack.
- General cleanup of several functions, comments, TODOs, etc.
- main.rs was moved to make room for upcoming improvements to the UI
TODO:
- REPL mode is only partially compatible with .define directive
- Branching to a label will branch to the data AT the label,
not the label itself. I doubt this is correct behavior.
- In case br <label> is meant to use the absolute address,
I've created a .org directive (currently unimplemented)
for specifying the load address of the program.
2023-09-05 06:54:50 +00:00
|
|
|
jmp _register_mode
|
2023-08-20 04:02:24 +00:00
|
|
|
jmp 3fe
|
|
|
|
jmp -3fc
|
|
|
|
ret
|
|
|
|
|
|
|
|
; Funky encodings
|
|
|
|
mov r6, r4
|
|
|
|
mov @r6, r4
|
|
|
|
mov @r6+, r4
|
|
|
|
mov 0(r6), r4
|
|
|
|
mov 4141(r6), r4
|
|
|
|
mov #-1, r4
|
|
|
|
mov #ffff, r4
|
|
|
|
mov #0, r4
|
|
|
|
mov #1, r4
|
|
|
|
mov #2, r4
|
|
|
|
mov #4, r4
|
|
|
|
mov #8, r4
|
|
|
|
mov r6, 0(r4)
|
|
|
|
mov @r6, 0(r4)
|
|
|
|
mov @r6+, 0(r4)
|
|
|
|
mov 0(r6), 0(r4)
|
|
|
|
mov 4141(r6), 0(r4)
|
|
|
|
mov #-1, 0(r4)
|
|
|
|
mov #ffff, 0(r4)
|
|
|
|
mov #0, 0(r4)
|
|
|
|
mov #1, 0(r4)
|
|
|
|
mov #2, 0(r4)
|
|
|
|
mov #4, 0(r4)
|
|
|
|
mov #8, 0(r4)
|
|
|
|
mov r6, 4141(r4)
|
|
|
|
mov @r6, 4141(r4)
|
|
|
|
mov @r6+, 4141(r4)
|
|
|
|
mov 0(r6), 4141(r4)
|
|
|
|
mov 4141(r6), 4141(r4)
|
|
|
|
mov #-1, 4141(r4)
|
|
|
|
mov #ffff, 4141(r4)
|
|
|
|
mov #0, 4141(r4)
|
|
|
|
mov #1, 4141(r4)
|
|
|
|
mov #2, 4141(r4)
|
|
|
|
mov #4, 4141(r4)
|
|
|
|
mov #8, 4141(r4)
|
|
|
|
mov r6, #0
|
|
|
|
mov @r6, #0
|
|
|
|
mov @r6+, #0
|
|
|
|
mov 0(r6), #0
|
|
|
|
mov 4141(r6), #0
|
|
|
|
mov #-1, #0
|
|
|
|
mov #ffff, #0
|
|
|
|
mov #0, #0
|
|
|
|
mov #1, #0
|
|
|
|
mov #2, #0
|
|
|
|
mov #4, #0
|
|
|
|
mov #8, #0
|
|
|
|
mov r6, #1
|
|
|
|
mov @r6, #1
|
|
|
|
mov @r6+, #1
|
|
|
|
mov 0(r6), #1
|
|
|
|
mov 4141(r6), #1
|
|
|
|
mov #-1, #1
|
|
|
|
mov #ffff, #1
|
|
|
|
mov #0, #1
|
|
|
|
mov #1, #1
|
|
|
|
mov #2, #1
|
|
|
|
mov #4, #1
|
|
|
|
mov #8, #1
|
|
|
|
|
|
|
|
; Instruction exercise
|
|
|
|
; Jumps
|
|
|
|
jne 10
|
|
|
|
jeq 10
|
|
|
|
jlo 10
|
|
|
|
jhs 10
|
|
|
|
jn 10
|
|
|
|
jge 10
|
|
|
|
jl 10
|
|
|
|
jmp 10
|
|
|
|
|
|
|
|
; Two-ops
|
|
|
|
mov r14, r15
|
|
|
|
add r14, r15
|
|
|
|
addc r14, r15
|
|
|
|
subc r14, r15
|
|
|
|
sub r14, r15
|
|
|
|
cmp r14, r15
|
|
|
|
dadd r14, r15
|
|
|
|
bit r14, r15
|
|
|
|
bic r14, r15
|
|
|
|
bis r14, r15
|
|
|
|
xor r14, r15
|
|
|
|
and r14, 10(r15)
|
|
|
|
|
|
|
|
; One-ops
|
|
|
|
rrc r15
|
|
|
|
swpb r15
|
|
|
|
rra r15
|
|
|
|
sxt r15
|
|
|
|
push r15
|
|
|
|
call r15
|
|
|
|
reti r15
|
|
|
|
|
|
|
|
; Jump aliases
|
|
|
|
jnc 10
|
|
|
|
jnz 10
|
|
|
|
jc 10
|
|
|
|
jz 10
|
|
|
|
|
|
|
|
; "emulated" no-op instructions
|
|
|
|
ret
|
|
|
|
clrc
|
|
|
|
setc
|
|
|
|
clrz
|
|
|
|
setz
|
|
|
|
clrn
|
|
|
|
setn
|
|
|
|
dint
|
|
|
|
eint
|
|
|
|
nop
|
|
|
|
|
|
|
|
; "emulated" one-op instructions
|
|
|
|
br r15
|
|
|
|
pop r15
|
|
|
|
rla r15
|
|
|
|
rlc r15
|
|
|
|
inv r15
|
|
|
|
clr r15
|
|
|
|
tst r15
|
|
|
|
dec r15
|
|
|
|
decd r15
|
|
|
|
inc r15
|
|
|
|
incd r15
|
|
|
|
adc r15
|
|
|
|
dadc r15
|
|
|
|
sbc r15
|