mirror of
https://github.com/notwa/lips
synced 2024-11-13 22:29:03 -08:00
use ; comments to fix github highlighting
This commit is contained in:
parent
9e4167e04a
commit
0b5331ff5c
2 changed files with 71 additions and 70 deletions
38
README.md
38
README.md
|
@ -52,49 +52,51 @@ It takes a couple notes from more traditional assemblers as well.
|
|||
[caje]: https://github.com/Tarek701/CajeASM/
|
||||
|
||||
A run-down of various syntax elements:
|
||||
```
|
||||
```asm
|
||||
// this is a comment
|
||||
/* this is a block comment */
|
||||
; this is a more traditional assembly style of comment
|
||||
; we'll be using this so github's syntax highlighting doesn't blow up
|
||||
|
||||
// this is comparible to C's #define my_const 0xDEADBEEF
|
||||
; this is comparible to C's #define my_const 0xDEADBEEF
|
||||
[my_const]: 0xDEADBEEF
|
||||
// we can then use it in instructions with a @ prefix
|
||||
; we can then use it in instructions by adding a @ prefix
|
||||
li a0, @my_const
|
||||
|
||||
// whitespace is optional
|
||||
; whitespace is optional
|
||||
li a0,@myconst
|
||||
// commas can be optional too,
|
||||
// but this feature will likely be removed in the future.
|
||||
; commas can be optional too,
|
||||
; but this feature will likely be removed in the future.
|
||||
li a0 @myconst
|
||||
// instruction/register names are case-insensitive, as are hex digits
|
||||
; instruction/register names are case-insensitive, as are hex digits
|
||||
LI A0, @my_const
|
||||
LuI a0, 0xDeAd
|
||||
// coprocessor 0 registers are case-insensitive as well,
|
||||
// though this may change in the future.
|
||||
; coprocessor 0 registers are case-insensitive as well,
|
||||
; though this may change in the future.
|
||||
mfc0 a1, CouNT
|
||||
|
||||
// labels are defined with a colon and referenced without prefix, as such:
|
||||
; labels are defined with a colon and referenced without prefix, as such:
|
||||
my_label:
|
||||
b my_label
|
||||
nop
|
||||
// directives are prefixed with a dot.
|
||||
// also, labels may be used in .word directives.
|
||||
; directives are prefixed with a dot.
|
||||
; also, labels may be used in .word directives.
|
||||
.word my_label, 1, 2, 3, 0x4567
|
||||
// octal numbers are supported
|
||||
; octal numbers are supported
|
||||
.short 0177, 0404
|
||||
.align // implied argument of 2, for a 2**n=4 byte alignment
|
||||
.align ; implied argument of 2, for a 2**n=4 byte alignment
|
||||
|
||||
// loading and storing can be written in several ways (addressing modes)
|
||||
; loading and storing can be written in several ways (addressing modes)
|
||||
lw s0, label
|
||||
lw s1, (s0)
|
||||
lw s2, 256(s0)
|
||||
lw s3, label(s0)
|
||||
|
||||
// this is currently unsupported however
|
||||
; this is currently unsupported however
|
||||
sw s2, label+4
|
||||
sw s3, label+4(s0)
|
||||
|
||||
// relative labels, borrowed from asw (except ours require a suffixing colon)
|
||||
; relative labels, borrowed from asw (except ours require a suffixing colon)
|
||||
-:
|
||||
b ++
|
||||
nop
|
||||
|
@ -106,7 +108,7 @@ my_label:
|
|||
b -
|
||||
nop
|
||||
|
||||
// TODO: more examples!
|
||||
; TODO: more examples!
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
|
103
example.asm
103
example.asm
|
@ -1,98 +1,97 @@
|
|||
/* lips example code: fibonacci numbers
|
||||
* this isn't a particularily useful or realistic example,
|
||||
* but it demonstrates syntax and various features in lips.
|
||||
*/
|
||||
; lips example code: fibonacci numbers
|
||||
; this isn't a particularily useful or realistic example,
|
||||
; but it demonstrates syntax and various features in lips.
|
||||
|
||||
[max_n]: 47
|
||||
|
||||
fib:
|
||||
// calculate the nth fibonacci number, caching results 1 to 47 to a table
|
||||
// only valid for values of n between 0 and 47 inclusive.
|
||||
// a0: n
|
||||
// v0: Fn
|
||||
; calculate the nth fibonacci number, caching results 1 to 47 to a table
|
||||
; only valid for values of n between 0 and 47 inclusive.
|
||||
; a0: n
|
||||
; v0: Fn
|
||||
|
||||
// branch to return 0 if a0 <= 0.
|
||||
// the + refers to the next + label, relative to here.
|
||||
// ++ would refer to the + label after that, and so on.
|
||||
; branch to return 0 if a0 <= 0.
|
||||
; the + refers to the next + label, relative to here.
|
||||
; ++ would refer to the + label after that, and so on.
|
||||
blez a0, +
|
||||
|
||||
// note that this executes even if the branch is taken,
|
||||
// due to the single delay slot of this MIPS CPU.
|
||||
// pseudo-instruction clears (sets to 0) the 32-bit value of a register:
|
||||
; note that this executes even if the branch is taken,
|
||||
; due to the single delay slot of this MIPS CPU.
|
||||
; pseudo-instruction clears (sets to 0) the 32-bit value of a register:
|
||||
cl v0
|
||||
|
||||
// check if the input is within the bounds specified earlier.
|
||||
// pseudo-instruction to branch if register > immediate:
|
||||
; check if the input is within the bounds specified earlier.
|
||||
; pseudo-instruction to branch if register > immediate:
|
||||
bgti a0, @max_n, +
|
||||
|
||||
// offset the input for use with the look-up table.
|
||||
// note that this executes even if the branch is taken,
|
||||
// but won't break the functionality of the routine either way.
|
||||
// pseudo-instruction translates into an addiu with a negated immediate:
|
||||
; offset the input for use with the look-up table.
|
||||
; note that this executes even if the branch is taken,
|
||||
; but won't break the functionality of the routine either way.
|
||||
; pseudo-instruction translates into an addiu with a negated immediate:
|
||||
subiu t0, a0, 1
|
||||
|
||||
// multiply by sizeof(word) which is 4, or 1 << 2.
|
||||
; multiply by sizeof(word) which is 4, or 1 << 2.
|
||||
sll t0, t0, 2
|
||||
|
||||
// load the value from the look-up table.
|
||||
// pseudo-instruction utilizing addressing modes:
|
||||
; load the value from the look-up table.
|
||||
; pseudo-instruction utilizing addressing modes:
|
||||
lw t9, fib_cache(t0)
|
||||
|
||||
// branch to return the look-up value if it's non-zero, meaning it has been cached.
|
||||
; branch to return the look-up value if it's non-zero, meaning it has been cached.
|
||||
bnez t9, +
|
||||
|
||||
// once again, note that this is the delay slot of the branch instruction.
|
||||
// pseudo-instruction to copy the 32-bit value of one register to another:
|
||||
; once again, note that this is the delay slot of the branch instruction.
|
||||
; pseudo-instruction to copy the 32-bit value of one register to another:
|
||||
mov v0, t9
|
||||
|
||||
// set up the following loop to calculate the fibonacci number.
|
||||
// pseudo-instruction to load a 32-bit value into a register:
|
||||
li t1, 0 // F(0)
|
||||
li t2, 1 // F(1)
|
||||
; set up the following loop to calculate the fibonacci number.
|
||||
; pseudo-instruction to load a 32-bit value into a register:
|
||||
li t1, 0 ; F(0)
|
||||
li t2, 1 ; F(1)
|
||||
|
||||
-: // here's a - label referred to later.
|
||||
// - labels are like + labels, except
|
||||
// they look upwards in the file instead of downwards.
|
||||
-: ; here's a - label referred to later.
|
||||
; - labels are like + labels, except
|
||||
; they look upwards in the file instead of downwards.
|
||||
|
||||
// calculate the next fibonacci number.
|
||||
; calculate the next fibonacci number.
|
||||
addu t3, t1, t2
|
||||
|
||||
// push the previous values back, part 1.
|
||||
; push the previous values back, part 1.
|
||||
mov t1, t2
|
||||
|
||||
// iterate to the next number.
|
||||
; iterate to the next number.
|
||||
subiu a0, a0, 1
|
||||
|
||||
// loop if it hasn't yet reached the nth fibonacci number.
|
||||
; loop if it hasn't yet reached the nth fibonacci number.
|
||||
bnez a0, -
|
||||
|
||||
// push the previous values back, part 2.
|
||||
// this is put in the branch delay as a simple optimization.
|
||||
; push the previous values back, part 2.
|
||||
; this is put in the branch delay as a simple optimization.
|
||||
mov t2, t3
|
||||
|
||||
// loop finished, copy the result to return.
|
||||
; loop finished, copy the result to return.
|
||||
mov v0, t1
|
||||
|
||||
// cache the result for next time.
|
||||
// pseudo-instruction not unlike the previous lw:
|
||||
; cache the result for next time.
|
||||
; pseudo-instruction not unlike the previous lw:
|
||||
sw v0, fib_cache(t0)
|
||||
|
||||
// here's the + label used at the start of the routine.
|
||||
; here's the + label used at the start of the routine.
|
||||
+:
|
||||
// return to the function that called this routine.
|
||||
// when jr is given without any arguments, `jr ra` is implied.
|
||||
; return to the function that called this routine.
|
||||
; when jr is given without any arguments, `jr ra` is implied.
|
||||
jr
|
||||
|
||||
// there's nothing to do in the delay slot, so don't do anything.
|
||||
// this is necessary, otherwise the next instruction or data
|
||||
// following the routine would be executed.
|
||||
// pseudo-instruction to do nothing:
|
||||
; there's nothing to do in the delay slot, so don't do anything.
|
||||
; this is necessary, otherwise the next instruction or data
|
||||
; following the routine would be executed.
|
||||
; pseudo-instruction to do nothing:
|
||||
nop
|
||||
|
||||
// set up initial values in the look-up table.
|
||||
; set up initial values in the look-up table.
|
||||
fib_cache:
|
||||
// lips doesn't yet have a way to specify "x, n times",
|
||||
// so this will do for now.
|
||||
; lips doesn't yet have a way to specify "x, n times",
|
||||
; so this will do for now.
|
||||
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
|
Loading…
Reference in a new issue