ARMLite
- This article is not detailed enough and needs to be expanded. Please help us by adding some more information.
ARMLite is an educational assembly language based on the ARM architecture, made by Peter Higginson with help from Richard Pawson.
Overview
Contrary to many other esolangs, ARMLite does not have a local-machine implementation (or not any that the writer of this article is aware of). Instead, programs written in the language are interpreted and ran on its website.
ARMLite operates on a simulated computer, with 13 general-purpose registers marked from R0 to R12, and 3 other registers which are the Link Register (LR), Stack Pointer (SP) and Program Counter (PC). The computer also features ~1Mb of memory. All registers and memory used 32-bit integer words. There's also a input/output stream for text-based IO, as well as a graphical monitor that can be changed between different resolutions called "modes": low-res, mid-res and high-res.
In order to write your program, click on the button named "Edit" under the "Program" text area. Then, once you are done, press "Submit" and the website will automatically format your code, as well as report on errors.
For other uses of the site (such as breakpoints and debugging), consult the manual
Register arithmetic
ARMLite uses registers as its main method of handling arithmetic operations. The LR, SP and PC registers can also be manipulated the same way as the general purpose registers, although this is only recommended if you know what you are doing.
Instruction | Syntax | Usage | Example | Notes |
---|---|---|---|---|
MOV | MOV <dest_register> #<value> | Stores specified value into <dest_register>. | MOV R0, #15 | A register can be used in place of #<value> |
ADD | ADD <dest_register>, <source_register_1>, <source_register_2> | Stores <dest_register> as the value of <source_register_1> + <source_register_2> | ADD R2, R1, R0 | A value can be used in place of <source_register_2>, but not <source_register_1> |
SUB | SUB <dest_register>, <source_register_1>, <source_register_2> | Similar to ADD but with subtraction instead of addition | SUB R2, R1, R0 | A value can be used in place of <source_register_2>, but not <source_register_1> |
OR | OR <dest_register>, <source_register_1>, <source_register_2> | Similar to ADD but with bitwise or instead of addition | OR R2, R1, R0 | A value can be used in place of <source_register_2>, but not <source_register_1> |
AND | AND <dest_register>, <source_register_1>, <source_register_2> | Similar to ADD but with bitwise and instead of addition | AND R2, R1, R0 | A value can be used in place of <source_register_2>, but not <source_register_1> |
XOR | SUB <dest_register>, <source_register_1>, <source_register_2> | Similar to ADD but with bitwise xor instead of addition | XOR R2, R1, R0 | A value can be used in place of <source_register_2>, but not <source_register_1> |
LSL | LSL <dest_register>, <source_register>, #<value> | Shifts <source_register>`` left by ``<value>`` bits, padding with zeros and discarding all bits past the 32th bit. | LSL R1, R0, #1 | A register can be used in place of #<value> |
LSR | LSR <dest_register>, <source_register>, #<value> | Shifts <source_register>`` right by ``<value>`` bits, padding with zeros and discarding all bits past the 1st bit. | LSL R1, R0, #1 | A register can be used in place of #<value> |
MVN | MVN <dest_register> #<value> | Store <value> into <dest_register>, but every bit flipped | MVN R0, #0 | A register can be used in place of #<value> |
In ARMLite, integer values can be specified in different bases by applying prefixes: 0x for hex and 0b for binary. However, to indicate an immediate value, you still need to prepend a '#' symbol beforehand. E.g. #0xA would be equivalent to 10.
Labels and control flow
In ARMLite, labels are usually stated by their name, followed by :
, such as label:
. They can be followed by instructions, which will execute when ARMLite reaches the label by either branching or if the program reaches there normally (e.g. if the line with a label is reached right after another line). Note that while ARMLite instructions and register names are case-insensitive, labels are case-sensitive,
ARMLite supports various types of branches, that can be divided into three central types: conditionless, comparison-condition, and arithmetic-condition.
Conditionless branches
Instruction | Syntax | Usage |
---|---|---|
B | B label | Perform a conditionless branch into a label |
BL | BL label | Perform a conditionless branch into a label, but saves to LR the address of the next instruction right after the BL (also see the RET command) |
While not a branch instruction, the RET command moves the program counter to the address stored in the value of the LR. This means that after BL'ing to a label, the RET command would then make program execution continue from right after the BL.
Comparison-condition branches
Unlike other languages where
Arithmetic-condition branches
Memory
ARMLite uses a 32-bit per word model for memory, with each word taking up four successive bytes (registers themselves are also 32 bit). Memory is accessible at the byte and word level. ARMLite does not have any mechanism to interact directly with memory, instead all interactions are done through entirely through registers.
Instruction | Syntax | Usage | Example | Notes | |
---|---|---|---|---|---|
LDR | LDR <dest_register>, [<register_containing_address>] | Loads the 32-bit word from the address stored inside <register_containing_address> to <dest_register> | LDR R1, [R0] | LDR and STR requires <register_containing_address> to have a value divisible by 4. Otherwise the programs throws an Unaligned access runtime error | |
STR | STR <dest_register>, [<register_containing_address>] | Stores the 32-bit value from <dest_register> to the address stored inside <register_containing_address> | STR R1, [R0] | LDR and STR requires <register_containing_address> to have a value divisible by 4. Otherwise the programs throws an Unaligned access runtime error | |
LDRB | LDRB <dest_register>, [<register_containing_address>] | Loads a single byte from address stored inside <register_containing_address> to <dest_register> | LDRB R1, [R0] | ||
STRB | STRB <dest_register>, [<register_containing_address>] | Stores a single byte from <dest_register> to address stored inside <register_containing_address> | STRB R1, [R0] |
Comments
ARMLite only has line comments, which starts with either ;
or //
, taking everything until the end of line. Comments are highlighted in green when submitted, and ignored when running.
Example programs
Hello, World!
Prints "Hello, World!"
MOV R0, #helloworld
STR R0, .WriteString
helloworld: .asciz "Hello, World!"
Count integers from 1 to N
LDR R0, .InputNum
loop:
ADD R1, R1, #1
STR R1, .WriteUnsignedNum
CMP R1, R0
BLT loop
Truth machine
LDR R0, .InputNum
CMP R0, #1
BEQ loop
HALT
loop:
STR R0, .WriteUnsignedNum
B loop
Shortest infinite loop
RET
Deadfish interpreter
See ARMLite