UNC-101 Architecture Simulator V 0.1


1.0 UNC-101 Processor Architecture

The UNC-101 is a 16-bit processor with 15 registers, and a main memory size of 65536 (216) 16-bit words. It has a small, but capable instruction set. All instructions are either one or two words in length.

The fifteen registers are specified as $1-$15. Each register holds a 16-bit value, which can be interpreted a number, a character, or any sort of variable. The special operand, $0, can be used anywhere a register is appropriate. The contents of $0, when used as a source operand, is always 0x0000. Likewise, all writes to $0 are ignored.

Program execution begins at location 0x0000. However, the program must first be assembled (converted from its symbolic representation to a sequence of 16-bit words in memory) before it can be executed. If there are errors in the assembly process, a dialog box will pop up explaining the error.

2.0 Introduction to UNC-101 Assembly Language

A typical line of assembly code specifies a single primitive operation, called an instruction, and its operands. The list of all UNC-101 operations (its instruction set) is enumerated in section 3. In an assembly language instructions are specified via short mneumonics of the operation specified (usually either abbreviations of acronymns). A list of comma-separated operands follows each instruction's mneumonic. The assembler uses this mneumonic and operand list to generate a binary encoding of the instruction, which is stored into the next available memory location. Thus, an assembly language program is merely a way of generating a sequence of binary words, that the computer interprets as either (or both) program or data. To make this discussion concrete, consider the following example line of assembly code:

add $3,$4,$4 "add" is the instruction mneumonic
"$3,$4,$4" is a list of 3 operands

Generally, he first operand specifies the destination (output) of the operation, and subsequent operands specify the source (input) operands. The instruction given tells the UNC-101 to add the contents register 4 to itself and store the result into register 3.

Empty lines are ignored by the assmebler (they generate no output to memory), but they are often used to enhance readability. Any text following a "#" is considered a comment and is ignored by the assembler. Comments are used to document the intent of the code beyond what is evident from the instruction specification alone.

Optionally, any line of assembly code can start with a label. A label is a sequence of characters followed by a colon (":"), which it is usually a meaningful name. A label provides a means for referencing the memory location that a particular instruction or data is stored in. Instruction labels are often used to specify targets for branch instuctions. In the case of data, a label might represent a variable name. An example using label is shown below:

loop: subi $3,$3,1 # loop is a label
bne $0,$5,$0,loop # here the label is referenced

The UNC-101 assembler also provides a small set of assembler directives, that are used like instructions. All assembler directives are prefixed with a "." (period) and they are generally used for allocating space for data and initializing variables. A complete list of assembler directives is given in section 4. Examples are given below.

Fib: .data 1,1,2,3,5,8,13,21 # first 8 Fibonacci numbers
masks: .data 0x00ff,0xff00 # byte masks
Name: .string "Leonard" # 0-terminated string (8 words)
array: .space 20 # 20 uninitialized words

The UNC-101 assembler also provides special simulator support. Any line of assembly code beginning with an "*" (asterix) will act as a breakpoint causing the simulator to halt prior to the execution of the instruction following the mark, or after marked data is accessed via either a load or store instruction. One or more breakpoints can be set, and at least one is required to use the "Run" button.

3.0 UNC-101 Instruction Set

Math Instructions

ADD: add
Syntax: add $d,$a,$b
Encoding: 0000ddddaaaabbbb
Description:
Reg[d] ← Reg[a] + Reg[b]

Adds the contents of two registers (a and b), and places the result in a third register (d).

Example: add $6,$2,$0 # Encoded as: 0x0620


ADDI: add immediate
Syntax: addi $d,$a,imm16
Encoding: 1110ddddaaaa0000 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Reg[a] + imm16

Adds a 16-bit constant to the contents of register (a), and places the result in register d.

Example: addi $6,$2,100 # Encoded as: 0xe620 0x0064


SUB: subtract
Syntax: sub $d,$a,$b
Encoding: 0100ddddaaaabbbb
Description:
Reg[d] ← Reg[a] - Reg[b]

Sutracts the contents of one registers (b) from another (a), and places the result in a third register (d).

Example: sub $1,$4,$12 # Encoded as: 0x414c


SUBI: subtract immediate
Syntax: subi $d,$a,imm16
Encoding: 1110ddddaaaa0100 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Reg[a] + imm16

Subtracts a 16-bit constant from the contents of register (a), and places the result in register d.

Example: subi $6,$2,10 # Encoded as: 0xe624 0x000a


SGT: set if greater than
Syntax: sgt $d,$a,$b
Encoding: 0101ddddaaaabbbb
Description:
Reg[d] ← 1 if (Reg[a] > Reg[b]); 0 otherwise

Set the destination register d to '1' if the contents of register a is greater than the contents of register (b).

Example: sgt $6,$10,$1 # Encoded as: 0x56a1


SGTI: set if greater than immediate
Syntax: sgti $d,$a,imm16
Encoding: 1110ddddaaaa0101 iiiiiiiiiiiiiiii
Description:
Reg[d] ← 1 if (Reg[a] > imm16); 0 otherwise

Sets the destination register d to '1' if the contents of register a is greater than the specified 16-bit signed constant.

Example: sgti $6,$2,10 # Encoded as: 0xe625 0x000a


SGE: set if greater than or equal
Syntax: sge $d,$a,$b
Encoding: 0110ddddaaaabbbb
Description:
Reg[d] ← 1 if (Reg[a] ≥ Reg[b]); 0 otherwise

Set the destination register d to '1' if the contents of register a is greater than or equal to the contents of register (b).

Example: sge $11,$4,$2 # Encoded as: 0x6b42


SGEI: set if greater than or equal immediate
Syntax: sgei $d,$a,imm16
Encoding: 1110ddddaaaa0110 iiiiiiiiiiiiiiii
Description:
Reg[d] ← 1 if (Reg[a] ≥ imm16); 0 otherwise

Sets the destination register d to '1' if the contents of register a is greater than or equal to the specified 16-bit signed constant.

Example: sgei $6,$2,-10 # Encoded as: 0xe626 0xfff6



Logic Instructions

AND: bitwise and
Syntax: and $d,$a,$b
Encoding: 0001ddddaaaabbbb
Description:
Reg[d] ← Reg[a] & Reg[b]

Performs a "bitwise" anding of the contents of two registers (a and b), and places the result in a third reigster (d).

Example: and $6,$2,$0 # Encoded as: 0x1620


ANDI: bitwise and immediate
Syntax: andi $d,$a,imm16
Encoding: 1110ddddaaaa0001 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Reg[a] & imm16

Performs a "bitwise" anding of the contents of registers a with the given 16-bit constant and places the result register d.

Example: andi $6,$2,15 # Encoded as: 0xe621 0x000f


OR: bitwise or
Syntax: or $d,$a,$b
Encoding: 0010ddddaaaabbbb
Description:
Reg[d] ← Reg[a] | Reg[b]

Performs a "bitwise" oring of the contents of two registers (a and b), and places the result in a third reigster (d).

Example: or $1,$1,$2 # Encoded as: 0x2112


ORI: bitwise or immediate
Syntax: ori $d,$a,imm16
Encoding: 1110ddddaaaa0010 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Reg[a] | imm16

Performs a "bitwise" oring of the contents of registers a with the given 16-bit constant and places the result register d.

Example: ori $6,$2,0x00ff # Encoded as: 0xe622 0x0ff


XOR: bitwise exclusive or
Syntax: xor $d,$a,$b
Encoding: 0011ddddaaaabbbb
Description:
Reg[d] ← Reg[a] ^ Reg[b]

Performs a "bitwise" exclusive-oring of the contents of two registers (a and b), and places the result in a third reigster (d).

Example: xor $6,$9,$1 # Encoded as: 0x3691


XORI: bitwise exclusive-or immediate
Syntax: xori $d,$a,imm16
Encoding: 1110ddddaaaa0011 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Reg[a] ^ imm16

Performs a "bitwise" exclusive-oring of the contents of registers a with the given 16-bit constant and places the result register d.

Example: xori $6,$2,-1 # Encoded as: 0xe213 0xffff



Shift Instructions

SHL: shift left
Syntax: shl $d,$a,imm4
Encoding: 1001ddddaaaaiiii
Description:
Reg[d] ← Reg[a] << imm4

Shift the contents of register a left the number of positions specified by the specified unsigned constant (0-15). Vacated register bits are filled with 0's.

Example: shl $6,$2,2 # Encoded as: 0x9622


SHR: shift right
Syntax: shr $d,$a,imm4
Encoding: 1010ddddaaaaiiii
Description:
Reg[d] ← Reg[a] >> imm4

Shift the contents of register a right the number of positions specified by the specified unsigned constant (0-15). Vacated register bits are filled with 0's.

Example: shr $1,$1,8 # Encoded as: 0xa118


SRA: shift right arithemetic
Syntax: sra $d,$a,imm4
Encoding: 1011ddddaaaaiiii
Description:
Reg[d] ← Reg[a] >>> imm4

Shift the contents of register a right the number of positions specified by the specified unsigned constant (0-15). Vacated register bits are filled with copies of the sign bit. An alternate intepretation of is:
Reg[d] ← Reg[a] / 2imm4

Example: sra $1,$1,15 # Encoded as: 0xb11f


SRV: shift variable
Syntax: srv $d,$a,$b
Encoding: 1000ddddaaaabbbb
Description:
Reg[d] ← Reg[a] * 2Reg[b]

Shift the contents of register athe number of positions specified by the specified by the contents of register b, which is treated as a signed value. When the contents of register bare negative (implying a right shift), the vacated register bits are filled with copies of the sign bit. When the contents of register bare positive (implying a left shift), vacated register bits are filled with 0's.

Example: sra $1,$1,$2 # Encoded as: 0x8112



Memory Access Instructions

ST: store register
Syntax: st $d,$a
Encoding: 0111ddddaaaa1110
Description:
Memory[Reg[a]] ← Reg[d]

Save the contents of register d into the memory address given by the contents of register a.

Example: st $1,$14 # Encoded as: 0x71ee


LD: load register
Syntax: ld $d,$a
Encoding: 0111ddddaaaa1111
Description:
Reg[d] ← Memory[Reg[a]]

Load the register d with the contents of the memory location specified by the contents of register a.

Example: ld $1,$2 # Encoded as: 0x712f


STX: store register indexed
Syntax: stx $d,$a,imm16
Encoding: 1111ddddaaaa1110 iiiiiiiiiiiiiiii
Description:
Memory[Reg[a]+imm16] ← Reg[d]

Save the contents of register d into the memory address given by the sum of register a's contents added to the specified constant.

Example: stx $2,$3,0x1000 # Encoded as: 0xf23e 0x1000


LDX: load register indexed
Syntax: ldx $d,$a,imm16
Encoding: 1111ddddaaaa1111 iiiiiiiiiiiiiiii
Description:
Reg[d] ← Memory[Reg[a]+imm16]

Load the register d with the contents of the memory location specified by the sum of register a's contents and the specified constant.

Example: ldx $1,$2,40 # Encoded as: 0xf12f 0x0028



Branch and Jump Instructions

BEQ: branch if equal
Syntax: beq $d,$a,$b,imm16
Encoding: 1100ddddaaaabbbb iiiiiiiiiiiiiiii
Description:
if (Reg[a] = Reg[b]) {
    Reg[d] ← PC + 2
    PC ← imm16
}

If the contents of register a equals the contents of register b branch to the instruction given by the specified constant (usually a label) and save, the address of what would have been the following instruction in register d.

Example: beq $0,$0,$0,0 # Encoded as: 0xc000 0x0000


BNE: branch if not equal
Syntax: bne $d,$a,$b,imm16
Encoding: 1101ddddaaaabbbb iiiiiiiiiiiiiiii
Description:
if (Reg[a] ≠ Reg[b]) {
    Reg[d] ← PC + 2
    PC ← imm16
}

If the contents of register a and the contents of register b are not equal branch to the instruction given by the specified constant (usually a label) and save, the address of what would have been the following instruction in register d.

Example: bne $15,$1,$0,0x1000 # Encoded as: 0xdf10 0x1000


JR: jump through register
Syntax: jr $d,$a
Encoding: 0111ddddaaaa0000
Description:
Reg[d] ← PC + 1
PC ← Reg[a]

Jump to the instruction given by the contents of register a and save the address of what would have been the following instruction in register d.

Example: bne $15,$1,$0,0x1000 # Encoded as: 0xdf10 0x1000


JRX: jump through register indexed
Syntax: jrx $d,$a,imm16
Encoding: 1111ddddaaaa0000 iiiiiiiiiiiiiiii
Description:
Reg[d] ← PC + 1
PC ← Reg[a]+imm16

Jump to the instruction given by the sum of contents of register a with the immediate 16-bit constant. Save the address of the following instruction in register d.

Example: jrx $15,$1,0x1000 # Encoded as: 0xff10 0x1000


4.0 Assembler Directives

.DATA: Specify initialized data
Syntax: .data value1,value2, ..., valuen
Description:
Successive words in memory are initialized with constant values from the list. Constants can be decimal numbers, octal numbers prefixed with '0', hexadecimal numbers prefixed with '0x', or an address label.

Example: .data 10,010,0x10 # Encoded as: 0x000a, 0x0008, 0x0010


.SPACE: Specify a block of uninitialized space
Syntax: .space value1,value2, ..., valuen
Description:
Blocks of sizes specified in the list of constant values are reserved. Constants can be decimal numbers, octal numbers prefixed with '0', hexadecimal numbers prefixed with '0x', or an address label.

Example: .space 50 # reserves 50 uninitialized words


.STRING: Initialize memory with letters from strings
Syntax: .string "string1","string2", ..., "stringn"
Description:
Fills successive memory locations with characters from the given list of quoted strings, each string is termnated with a "0".

Example: .string "UNC" # Encoded as: 0x0055,0x004e,0x0043,0x0000