Lecture Main Points
Operation | Meaning |
---|---|
ADD a, b, c | Mem[a] = Mem[b] + Mem[c] |
XOR a, b, c | Mem[a] = Mem[b] ^ Mem[c] |
BZ target, c | if (Mem[c] == 0) PC = target |
opcode | dest | src0 | src1 |
Instruction | Encoding | |||
---|---|---|---|---|
opcode | dest | src0 | src1 | |
ADD | 0 | a | b | c |
XOR | 1 | a | b | c |
BZ | 2 | target | X | c |
If we wanted, for instance, to express the following sentiment: "Add the value in memory location 18 and the value in memory location 24 and place the result into memory location 15." We could write that in "human readable" form as follows:
ADD 15, 18, 24
0 | 15 | 18 | 24 |
Note that we've used decimal numbers in each position. Because each location in our instruction is a byte in size, it's often nice to write the encoded values in hex:
0 | A | 12 | 18 |
while (true) { IR = Mem[PC] PC = PC + 4 if (opcode(IR) == 0) Mem[dest(IR)] = Mem[src0(IR)] + Mem[src1(IR)] else if (opcode(IR) == 1) Mem[dest(IR)] =Mem[src0(IR)] ^ Mem[ src1(IR)] else if (opcode(IR) == 2) if (Mem[src2(IR)] == 0) PC = dest(IR) }
The sample program is the equivalent of the following bit of C code:
int A[5] = {-1, 0, 1, 2, 4}; int x; x = A[0] + A[1] + A[2] + A[3] + A[4];The assembly code (which would live in a file):
XOR 6, 6, 6 # x = 0 ADD 6, 6, 7 # x = A[0] ADD 6, 6, 8 # x += A[1] ADD 6, 6, 9 # x += A[2] ADD 6, 6, 0xa # x += A[3] ADD 6, 6, 0xb # x += A[4] .word 0 # this is 'x' .word 0xffffffff # this is A[0] .word 0x00000000 # A[1] .word 0x00000001 # A[2] .word 0x00000002 # A[3] .word 0x00000004 # A[4]The contents of memory when this program is loaded:
Address | Contents |
---|---|
0 | 0x01060606 |
1 | 0x00060607 |
2 | 0x00060608 |
3 | 0x00060609 |
4 | 0x0006060A |
5 | 0x0006060B |
6 | 0x00000000 |
7 | 0xFFFFFFFF |
8 | 0x00000000 |
9 | 0x00000001 |
A | 0x00000002 |
B | 0x00000004 |
There's a bug. What is it?
Now that memory is byte addressable, rather than word addressable as in SSI-0, have we really increased the maximum memory size allowed by the architecture?
Can we do still better, i.e., allow for an even bigger memory?
int A[512]; int index; int sum; sum = 0; for (index=0; index<512; index++) { if ( A[index) == 0 ) break; sum = sum + A[index]; }
Registers are one word (32-bits) wide.
Operation | Meaning |
---|---|
ADD rd, rs, rt | GPR[rd] = GPR[rs] + GPR[rt] |
XOR rd, rs, rt | GPR[rd] = GPR[rs] ^ GPR[rt] |
SR8 rd, rt | GPR[rd] = GPR[rt] >> 8 |
BZ target, rt | if (GRP[rt] == 0) PC = target |
LOAD rd, rt | GPR[rd] = Mem[GPR[rt]] |
STORE rd, rt | Mem[GPR[rt]] = GPR[rd] |
Bits | 31-29 | 28-27 | 26-18 | 17-9 | 8-0 |
---|---|---|---|---|---|
Use | opcode | Unused | rd | rs | rt |
For the branch instruction, I can use all of bits 28-9 for the target address.
xor 0, 0, 0 # register 0 will always be 0 xor 1, 1, 1 # register 1 is the running total - initialize it to 0 load 2, AddrOfA # register 2 holds the address of the next array element to add to the total load 3, five # register 3 holds the number of elements remaining to add to the total load 4, minus1 # register 4 will always hold -1 load 5, plus4 # register 5 will always hold 4 loop: load 6, 2 # fetch next element of array A add 1, 1, 6 # add that element to running total add 3, 3, 4 # subtract one from the count of number of elements to be added bz 3, done # are we done? add 2, 2, 5 # point register 2 at the next array element (because of byte addressing, +4) bz 0, loop # no - go back to the instruction at label 'loop' done: ??? # our usual problem that there's no way to 'stop' AddrOfA: .word address(A) five: .word 5 minus1: .word -1 plus4: .word 4 x: .word 0 A: .word -1 .word 0 .word 1 .word 2 .word 4