|
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
|
|