Dan Stone (dans@ontko.com)
April 11, 1999
This document describes the syntax of the IJVM Assembly Language, as expected by the mic1 IJVM Assembler. See the summary of IJVM instructions for an explanation of the default IJVM instructions.
Syntax:
.constant
constant1 value1
constant2 value2
.end-constant
Global constants are declared in the .constant section at the beginning of the file. The value of the constant can be given as a hexadecimal number (must be prefixed with "0x"), an octal number (must be prefixed with "0"), or a decimal number (no prefix). Declared constants may then be referred to by name, by an instruction expecting a constant as a parameter (i.e. LDC_W constant_name ). For example:
// this program displays all the printable ASCII values 32..126 .constant one 1 start 32 stop 126 .end-constant .main LDC_W start next: DUP OUT // output the current character DUP LDC_W stop ISUB IFEQ done // exit if we've reached the end LDC_W one IADD GOTO next // increment and do the next one done: POP HALT .end-main
The values of the constants are loaded into the constant pool, the area of memory denoted by the CPP.
In addition to user-defined constants, the absolute addresses of methods are also assembled into the constant pool. See the Methods section of this document for more information.
Syntax:
inside a .main or .method declaration
.var
var1
var2
.end-var
Local variables are declared inside a .main or .method section and may only be referenced by that main or method. There are no global variables.
Local variables are referenced by name (i.e. ISTORE var_name).
Labels are used to mark program lines for jump/goto instructions. Labels are only accessable from within the method in which they are declared. In other words, jumps may only occur within a method, not between methods.
Labels are words terminated by a colon. Labels are declared at the beginning of the line and mark the next program instruction. Below is a program fragment that illustrates the use of labels:
. . . ILOAD total LDC_W max_value ISUB IFLT lt_max // If total < max_value, goto lt_max GOTO gte_max // else (total >= max_value), goto gte_max lt_max: HALT gte_max: // Labels may be on seperate lines from the instructions they mark ERR
Syntax:
.main
-- variable declaration --
-- program contents --
.end-main
Every IJVM program must contain a .main method. .main must be declared before any other method.
Syntax:
.method method_name(param1, param2,...)
-- variable declaration --
-- method contents --
.end-method
When a method is declared, its byte address is added to the global constants and can be referenced by the method name. (i.e. INVOKEVIRTUAL method_name). Method parameters are declared by a comma-seperated list of the parameter names enclosed in parenthesis. The parameters are added to the local variables of the method and can be referenced by name within the method (i.e. ILOAD param1). If there are no parameters, use empty parenthesis.
Special care must be taken when invoking a method to ensure proper execution. A microprogram may expect a specific protocol to be followed in a method call. For example, the Mic1 microprogram, which is distributed with the mic1 software, requires the following steps to be taken when invoking a method:
Input and output are handled by the Main Memory module in the mic1 simulator. Main memory treats the highest memory addresses as an I/O device. If a word is written to this area, main memory writes the word's character value to the standard out text area of the simulator. If a word is read from this area of memory, main memory will return the next available value from an internal key buffer, which contains the character values of any user key-strokes. If the buffer is empty (no key has been pressed), a value of zero is returned.
The OUT command pops a word off the top of the stack and prints it to the standard out text area.
BIPUSH 0x41 // Push "A" OUT // Print "A"The IN command reads a character from the key buffer and pushes its value onto the stack. If no key is available to read (no key pressed, all keys have been read), zero will be pushed onto the stack. Therefore, it is usually a good idea for a program to loop until IN returns a valid value.
getch: IN // read character DUP // duplicate value for comparison IFEQ reread // if character=0 (no key press), goto reread GOTO done // else, goto done (character is valid key press) reread: POP // pop invalid number GOTO getch // try getting another character done: // key stroke is on top of stack
The IJVM assembler uses C++ style comments: // (double forward slash) indicates the start of a comment. Everything following //, up to the end-of-line character, is treated as a comment.
An .ijvm file contains a 32-bit magic number, which identifies the file as a program that can be executed on the mic1 simulator, and any number of data blocks. A data block has three parts, a 32-bit origin that indicates where in memory the block is to be loaded, a 32-bit byte count that indicates how many bytes of data are in the block, and the actual data bytes to be loaded into memory.
binary file = <32-bit magic number> [block]* block = <32-bit origin> <32-bit byte count>The 1.0 release of the IJVM Assembler creates two blocks, the constant pool and the program code.
Mnemonic | Operands | Description |
---|---|---|
BIPUSH | byte | Push a byte onto stack |
DUP | N/A | Copy top word on stack and push onto stack |
ERR | N/A | Print an error message and halt the simulator |
GOTO | label name | Unconditional jump |
HALT | N/A | Halt the simulator |
IADD | N/A | Pop two words from stack; push their sum |
IAND | N/A | Pop two words from stack; push Boolean AND |
IFEQ | label name | Pop word from stack and branch if it is zero |
IFLT | label name | Pop word from stack and branch if it is less than zero |
IF_ICMPEQ | label name | Pop two words from stack and branch if they are equal |
IINC | variable name, byte | Add a constant value to a local variable |
ILOAD | variable name | Push local variable onto stack |
IN | N/A | Reads a character from the keyboard buffer and pushes it onto the stack. If no character is available, 0 is pushed |
INVOKEVIRTUAL | method name | Invoke a method |
IOR | N/A | Pop two words from stack; push Boolean OR | IRETURN | N/A | Return from method with integer value |
ISTORE | variable name | Pop word from stack and store in local variable |
ISUB | N/A | Pop two words from stack; push their difference |
LDC_W | constant name | Push constant from constant pool onto stack |
NOP | N/A | Do nothing |
OUT | N/A | Pop word off stack and print it to standard out |
POP | N/A | Delete word from top of stack |
SWAP | N/A | Swap the two top words on the stack |
WIDE | N/A | Prefix instruction; next instruction has a 16-bit index |
Operand descriptions:
This required file contains descriptions of all of the instructions in the language. The description contains the opcodes, mnemonics, and parameter types (if any) of each instruction that is to be recognized by the assembler. This file can be altered and extended, as long as the microprogram is altered to support any changes made.