Assembly Language Reference 2010 02 18


This is a brief guide to explain the usage of the JavaScript Register Machine language, including a few simple examples of complete programs.

Each line in a program is either a label or a statement. A label defines a place in the program that can be jumped to, and can be used to create loops and branches. Labels are one or more lower case characters, followed by a colon, and should be on lines by themselves. e.g.,

init:
loop:

Statements all consist of the same basic format: the command, a register, and a word. There are eight commands, all containing three lower case letters, and they are described below. The commands are: end, jmp, jmz, cpy, cpo, mov, cor, out. Here is a sample command:

mov 0 10

This command moves the literal value "10" to register 0.

Registers:

Registers are where math happens, and are also the only place a program can write to directly. To get something to the machine's memory, it must first pass through a register. The core function defines 4 addressable registers, indexed as registers 0 through 3.

Words: A word is a decimal value of 16 bits, or in other words a number between 0 and 65535. All commands (except for mov)use the word to define a memory address to be referenced. A word can be a label instead of a number, and the compiler will look up the label's address from the symbol table when building the program, and substitute it for you. Here is an example of that, using the jmp command:

jmp 2 loop:

This will jump to the program location declared as "loop:", provided register 2 >= register 0.


Command reference:

Flow control statements:
jmp r l :: Jump to label l if register r >= register 0
0 l :: Always jump to label l. (Register 0 always equals itself)
jmz r l :: Jump to label l register r = 0
end :: Stop program.

When the end statement is reached, all output is flushed to the "output device" (textarea), and an alert window stating "End" pops up, allowing you to distinguish a finished program from an infinite loop.

Data bus:
cpy r a :: Copy address a to register r
cpo r a :: Copy register r to address a
mov r w :: Move literal value w to register r

Manipulate register data:
All of these commands copy the result of register r to memory address w, provided w is non-zero. (For mul and div, r is ignored, and register 0 is copied to address w.)

inc r w :: Increment register r
dec r w :: Decrement register r
add r w :: Add register 1 to register r
sub r w :: Subtract register 1 from register r
mul r w :: Multiply registers 0 and 1, product to register 0
div r w :: Divide register 0 by register 1, quotient to register 0, remainder to register 1

Bitwise operations:
rgt r w :: Right-shift register r by w bits
lft r w :: Left-shift register r by w bits

Output bus:
out r a :: Display value of address a
0 a :: Display numeric value of address a followed by newline
1 a :: Display unicode value of address a (charFromCode/CHR)

Commands can be followed by comments. After the word character is specified, you may add a space, and anything after is ignored by the compiler.

Here is a simple program to add two numbers and display their results:

mov 0 5 // Set value of register 0 to 5
mov 1 10 // Set value of register 1 to 10
add 0 50 // Add reg 1 to reg 0, copy reg 0 to memory addrss 50
out 0 50 // Display memory address 50 in decimal
end // Stop program


If you paste the above program into the Input textarea, then click "Run program", the correct answer "15" should be displayed in the Output textarea, as shown in this screenshot:



Here is a more complicated program that counts from 1 to 5, then back to 1. It shows the correct use of labels and jumping.

init:
mov 0 5 // Reg 0 = 5
mov 1 0 // Reg 1 = 0

inc:
inc 1 50 // Increment register 1, result to mem 50
out 0 50 // ...and display it as a decimal
jmp 1 dec: // Jump to dec when reg 1 = reg 0
jmp 0 inc: // Jump back to increment otherwise

dec:
dec 1 50 // Decrement register 1
jmz 1 fin: // Jump to end when register 1 = 0
out 0 50 // ...and display it as a decimal
jmp 0 dec: // Jump to dec:

fin:
end


The "init:" label above is superfluous, since no jump statement references it, but it doesn't hurt anything. Neither do the blank lines. A non-blank line that didn't fit the statement or label format, though, wouldn't be ok; you would see an error like this:


Comments: Post a Comment
<< Home

This page is powered by Blogger. Isn't yours?