Mark Floryan (mrf8t@virginia.edu)
Aaron Bloomfield (aaron@virginia.edu)
@github | ↑ |
Data Representation | Program Representation | |||||
string int x[3] char x 0x9cd0f0ad 01101011 |
![]() |
Objects Arrays Primitive types Addresses bits |
Java code C++ code C code x86 code IBCM hexadecimal |
![]() |
High-level language Low-level language Assembly language Machine code |
![]() |
|
![]() |
|
while(power is on) {
IR := memory[PC]
Increment PC by length of instruction
execute instruction in IR
}
add eax, ebx
add ecx, 1
load 100
add 200
store 300
| ![]() |
15 | 14 | 13 | 12 | 11 10 | ... | 0 | |
0 | 0 | 0 | 0 | |
(unused) | halt | |
0 | 0 | 0 | 1 | I/O op |
(unused) | I/O | |
0 | 0 | 1 | 0 | shift op |
(unused) | count | shifts |
opcode | address | |
others |
Op | Name | HLL meaning | Description |
---|---|---|---|
3 | load | a := mem[addr] | load accumulator from memory |
4 | store | mem[addr] := a | store accumulator into memory |
5 | add | a := a + mem[addr] | add memory to accumulator |
6 | sub | a := a - mem[addr] | subtract memory from accumulator |
7 | and | a := a ∧ mem[addr] | logical 'and' memory into accumulator |
8 | or | a := a ∨ mem[addr] | logical 'or' memory into accumulator |
9 | xor | a := a ⊕ mem[addr] | logical 'xor' memory into accumulator |
A | not | a := ~a | logical complement of accumulator |
B | nop | /* */ | do nothing (no operation) |
C | jmp | goto addr | jump to 'addr' |
D | jmpe | if a == 0 goto addr | jump to 'addr' if accumulator == zero |
E | jmpl | if a < 0 goto addr | jump to 'addr' if accum. is < zero |
F | brl | a := PC+1; goto addr | jump (branch) to 'addr'; set accum. to PC+1 (next inst) and jump |
start readH
loop load n
xit load s
dw
opcoden dw 0
declares a spot with label 'n' to have value 0load n
will load the value stored in that spot in memory
|
|
|
|
for ( i = 1; i < max; i++ ) ...
load one
store i
3016
4005
read n;
i = 1; // index in the array
s = 0; // ongoing sum
while (i <= n) {
s += i;
i += 1;
}
print s;
mem locn label op addr comments
C00A 000 jmp start skip around the variables
0000 001 i dw 0 int i
0000 002 s dw 0 int s
0000 003 n dw 0 int n
0001 004 one dw 1
0000 005 zero dw 0
0000 006 leave space for changes
0000 007
0000 008
0000 009
1000 00A start readH read n
4003 00B store n
3004 00C load one i = 1
4001 00D store i
3005 00E load zero s = 0
4002 00F store s
3003 010 loop load n if (i > n) goto xit
6001 011 sub i
E01A 012 jmpl xit
3002 013 load s s += i
5001 014 add i
4002 015 store s
3001 016 load i i += 1
5004 017 add one
4001 018 store i
C010 019 jmp loop goto loop
3002 01A xit load s print s
1800 01B printH
0000 01C halt halt
We'll look at this code in parts...
mem locn label op addr comments
C00A 000 jmp start skip around the vars
0000 001 i dw 0 int i
0000 002 s dw 0 int s
0000 003 n dw 0 int n
0001 004 one dw 1
0000 005 zero dw 0
...
1000 00A start readH read n
4003 00B store n
3004 00C load one i = 1
4001 00D store i
3005 00E load zero s = 0
4002 00F store s
mem locn label op addr comments
3003 010 loop load n if (i > n) goto xit
6001 011 sub i
E01A 012 jmpl xit
3002 013 load s s += i
5001 014 add i
4002 015 store s
3001 016 load i i += 1
5004 017 add one
4001 018 store i
C010 019 jmp loop goto loop
3002 01A xit load s print s
1800 01B printH
0000 01C halt halt
if (B == 0)
S1;
else
S2;
while(B >= 5)
S;
read a; // array base address
read n; // array size
i = 0; // index in the array
s = 0; // ongoing sum
while (i < n) {
s += a[i];
i += 1;
}
print s;
mem locn label op addr comments
C00A 000 jmp start skip around the variables
0000 001 i dw 0 int i
0000 002 s dw 0 int s
0000 003 a dw 0 int a[]
0000 004 n dw 0
0000 005 zero dw 0
0001 006 one dw 1
5000 007 adit dw 5000
0000 008 leave space for changes
0000 009
1000 00A start readH read array address
4003 00B store a
1000 00C readH read array size
4004 00D store n
3005 00E load zero i = 0; s = 0;
4001 00F store i
4002 010 store s
3004 011 loop load n if (i >= N) goto xit
6001 012 sub i
E020 013 jmpl xit
D020 014 jmpe xit
3007 015 load adit form the inst to add a[i]
5003 016 add a
5001 017 add i
401A 018 store doit plant inst into the code
3002 019 load s s += a[i]
0000 01A doit dw 0
4002 01B store s
3001 01C load i i += 1
5006 01D add one
4001 01E store i
C011 01F jmp loop goto loop
3002 020 xit load s print s
1800 021 printH
0000 022 halt
We'll look at this code in parts...
mem locn label op addr comments
C00A 000 jmp start skip around the vars
0000 001 i dw 0 int i
0000 002 s dw 0 int s
0000 003 a dw 0 int a[]
0000 004 n dw 0
0000 005 zero dw 0
0001 006 one dw 1
5000 007 adit dw 5000
... leave space for changes
1000 00A start readH read array address
4003 00B store a
1000 00C readH read array size
4004 00D store n
3005 00E load zero i = 0; s = 0;
4001 00F store i
4002 010 store s
...
3002 020 xit load s print s
1800 021 printH
0000 022 halt
mem locn label op addr comments
...
3004 011 loop load n if (i >= N) goto xit
6001 012 sub i
E020 013 jmpl xit
D020 014 jmpe xit
3007 015 load adit form inst to add a[i]
5003 016 add a
5001 017 add i
401A 018 store doit plant inst into code
3002 019 load s s += a[i]
0000 01A doit dw 0
4002 01B store s
3001 01C load i i += 1
5006 01D add one
4001 01E store i
C011 01F jmp loop goto loop
...
unsigned int x
unsigned int opcode = (x >> 12) & 0x000f
unsigned int ioshiftop = (x >> 10) & 0x0003
unsigned int address = x & 0x0fff
unsigned int shiftcount = x & 0x000f
unsigned int instruction = (opcode << 12) |
(ioshiftop << 10) | shiftcount
union ibcm_instruction {
#ifdef BIG_ENDIAN // the IBCM is big endian
struct { unsigned char high, low; } bytes;
#else
#ifdef LITTLE_ENDIAN
struct { unsigned char low, high; } bytes;
#else
#error Must define BIG_ENDIAN or LITTLE_ENDIAN
#endif // LITTLE_ENDIAN
#endif // BIG_ENDIAN
struct { unsigned int op:4, unused:12; } halt;
struct { unsigned int op:4, ioopt:2, unused:10 } io;
struct { unsigned int op:4, shiftop: 2,
unused:5, shiftcount:5; } shifts;
struct { unsigned int op:4, address:12; } others;
};
// read in instruction into unsigned chars a and b
ibcm_instruction inst;
inst.high = a;
inst.low = b;
if ( inst.halt.op == 0 ) { // halt
// ...
} else if ( inst.io.op == 1 ) { // io
cout << inst.io.ioopt << endl;
} else if ( inst.shifts.op == 2 ) { // shifts
cout << inst.shifts.shiftop << endl;
cout << inst.shifts.shiftcount << endl;
} else { // all others
cout << inst.others.address << endl;
}