Introduction to Computer Organization
Instruction Representation
S4 : 2023/2024
Review
• ISA: hardware / software interface
– Design principles, tradeoffs
• MIPS instructions
– Arithmetic: add/sub $t0, $s0, $s1
– Data transfer: lw/sw $t1, 8($s1)
• Operands must be registers
– 32 32-bit registers
– $t0 - $t7 => $8 - $15
– $s0 - $s7 => $16 - $23
• Memory: large, single dimension array of bytes M[232]
– Memory address is an index into that array of bytes
– Aligned words: M[0], M[4], M[8], ….M[4,294,967,292]
– Big/little endian byte order
Machine Language -- MIPS
• All instructions have the same length (32 bits)
• Good design demands good compromises
– Same instruction length or same format
• Three different formats
– R: arithmetic instruction format
– I: transfer, branch, immediate format
– J: jump instruction format
A[300] = h + A[300];
• add $t0, $s1, $s2
lw $t0, 1200($t1)
– 32 bits in machine language add $t0, $s2, $t0
– Fields for: sw $t0, 1200($t1)
– Operation (add) 10101101001010000000010010110000
• Operands ($s1, $s2, $t0) 00000010010010000100000000100000
10001101001010000000010010110000
Instruction Formats
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
R: op rs rt rd shamt funct
I: op rs rt address / immediate
J: op target address
op: basic operation of the instruction (opcode)
rs: first source operand register
rt: second source operand register
rd: destination operand register
shamt: shift amount
funct: selects the specific variant of the opcode (function code)
address: offset for load/store instructions (+/-215)
immediate: constants for immediate instructions
R Format
add $t0, $s1, $s2 (add $8, $17, $18 # $8 = $17 + $18)
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
0 17 18 8 0 32
000000 10001 10010 01000 00000 100000
sub $t1, $s1, $s2 (sub $9, $17, $18 # $9 = $17 - $18)
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
0 17 18 9 0 34
000000 10001 10010 01001 00000 100010
I Format
lw $t0, 52($s3) lw $8, 52($19)
6 bits 5 bits 5 bits 16 bits
35 19 8 52
100011 10011 01000 0000 0000 0011 0100
sw $t0, 52($s3) sw $8, 52($19)
6 bits 5 bits 5 bits 16 bits
43 19 8 52
101011 10011 01000 0000 0000 0011 0100
Example
A[300] = h + A[300]; /* $t1 <= base of array A; $s2 <= h */
Compiler
lw $t0, 1200($t1) # temporary register $t0 gets A[300]
add $t0, $s2, $t0 # temporary register $t0 gets h +A[300]
sw $t0, 1200($t1) # stores h + A[300] back into A[300]
Assembler
35 9 8 1200
0 18 8 8 0 32
43 9 8 1200
100011 01001 01000 0000 0100 1011 0000
000000 10010 01000 01000 00000 100000
101011 01001 01000 0000 0100 1011 0000
Immediates (Numerical Constants)
• Small constants are used frequently (50% of operands)
– A = A + 5;
– C = C – 1;
• Solutions
– Put typical constants in memory and load them
– Create hardwired registers (e.g. $0 or $zero)
• make the common case fast
• MIPS instructions for constants (I format)
– addi $t0, $s7, 4 # $t0 = $s7 + 4
8 23 8 4
001000 10111 01000 0000 0000 0000 0100
Arithmetic Overflow
• Computers have limited precision (32 bits)
15 1111
+3 0011
18 10010
• Some languages detect overflow (Ada), some don’t (C)
• MIPS provides 2 types of arithmetic instructions:
– Add, sub, and addi: cause overflow
– Addu, subu, and addiu: do not cause overflow
• MIPS C compilers produce addu, subu, addiu by default
Logical Instructions
• Bitwise operations
– View contents of registers as 32 bits rather than as a
single 32-bit number
• Instructions
– and, or: the 3 operands are registers (R format)
– andi, ori: the 3rd argument is an immediate (I format)
• Example: masks (andi $t0, $t0, 0xFFF)
1011 0110 1010 0100 0011 1101 1001 1010
0000 0000 0000 0000 0000 1111 1111 1111
0000 0000 0000 0000 0000 1101 1001 1010
Shift Instructions
• Move all the bits in a register to the left/right
– sll (shift left logical): fills emptied bits with 0s
– srl (shift right logical): fills emptied bits with 0s
– sra (shift right arithmetic): sign extends emptied bits
• Example: srl $t0, $s1, 8 (R format)
shamt
000000 00000 10001 01000 01000 000010
0001 0010 0011 0100 0101 0110 0111 0100
Zero Fill
0000 0000 0001 0010 0011 0100 0101 0110
Multiplication and Division
• Use special purpose registers (hi, lo)
– 32-bit value x 32-bit value = 64-bit value
• Mult $s0, $s1 000000 10000 10001 00000 00000 011000
– hi: upper half of product
– lo: lower half of product
• Div $s0, $s1 000000 10000 10001 00000 00000 011010
– hi: remainder ($s0 / $s1)
– lo: quotient ($s0 % $s1)
• Move results into general purpose registers:
– mfhi $s0 000000 00000 00000 10000 00000 010000
– mflo $s1 000000 00000 00000 10001 00000 010010
Assembly vs. Machine Language
• Assembly provides convenient symbolic representation
– Much easier than writing numbers
– Destination operand first
– Pseudo instructions
– Labels to identify and name words that hold instructions/data
• Machine language is the underlying reality
– Destination operand is no longer first
– Efficient format
• Assembly can provide pseudo instructions
– Move $t0, $t1 (add $t0, $t1, $zero)
• When considering performance (IC) you should count real
instructions
Register Conventions
Name Register Number Usage Preserved on call
$zero 0 the constant value 0 n.a.
$at 1 reserved for the assembler n.a.
$v0-$v1 2-3 value for results and expressions no
$a0-$a3 4-7 arguments (procedures/functions) yes
$t0-$t7 8-15 temporaries no
$s0-$s7 16-23 saved yes
$t8-$t9 24-25 more temporaries no
$k0-$k1 26-27 reserved for the operating system n.a.
$gp 28 global pointer yes
$sp 29 stack pointer yes
$fp 30 frame pointer yes
$ra 31 return address yes
New Topic – Decision Instructions
• Conditional branches
– If-then
– If-then-else
• Loops
– While
– Do while
– For
• Inequalities
• Switch statement
Conditional Branches
• Decision-Making Instructions
• Branch if equal
– beq register1, register2, destination_address
• Branch if not equal
– bne register1, register2, destination_address
• Example: beq $s3, $s4, 20
6 bits 5 bits 5 bits 16 bits
4 19 20 5
000100 10011 10100 0000 0000 0000 0101
Labels
• No need to calculate addresses for branches
if (i = = j) go to L1; f => $s0
g => $s1
f = g + h; h => $s2
i => $s3
L1: f = f – i; j => $s4
(4000) beq $s3, $s4, L1 # if i equals j go to L1
(4004) add $s0, $s1, $s2 # f = g + h
L1: (4008) sub $s0, $s0, $s3 # f = f - i
L1 corresponds to the address of the subtract instruction
If Statements
if (condition) if (condition) goto L1;
clause1; clause2;
else goto L2;
clause2; L1: clause1;
L2:
if (i = = j) beq $3, $4, True
f = g + h; sub $0, $s1, $s2
else j False
f = g - h; True: add $s0, $s1, $s2
False:
Loops
Loop: g = g + A[i]; Clever method of
i = i + j; multiplying by 4 to
get byte offset for
if (i != h) goto Loop; one word
Loop: add $t1, $s3 $s3 # $t1 = 2 * i
g: $s1 add $t1, $t1, $t1 # $t1 = 4 * I
h: $s2 add $t1, $t1, $5 # $t1=address of A[i]
i: $s3 lw $t0, 0($t1) # $t0 = A[i]
j: $s4 add $s1, $s1, $t0 # g = g + A[i]
Base of A: $s5 add $s3, $s3, $s4 # i = i + j
bne $s3, $s2, Loop # go to Loop if i != h
Basic Block
While Loop
while (save[i] = = k)
i = i +j;
# i: $s3; j: $s4; k: $s5; base of save: $s6
Loop: add $t1, $s3, $s3 # $t1 = 2 * i
add $t1, $t1, $t1 # $t1 = 4 * i
add $t1, $t1, $s6 # $t1 = address of save[i]
lw $t0, 0($t1) # $t0 = save[i]
bne $t0, $s5, Exit # go to Exit if save[i] != k
add $s3, $s3, $s4 # i = i +j
j Loop # go to Loop
Exit:
Number of instructions executed if save[i + m * j] does not equal k
for m = 10 and does equal k for 0 m 9 is 10 7 + 5 = 75
Optimization
add $t1, $s3, $s3 # Temp reg $t1 = 2 * i
Loop add $t1, $t1, $t1 # Temp reg $t1 = 4 * i
Partially add $t1, $t1, $s6 # $t1 = address of save[i]
Unrolled lw $t0, 0($t1) # Temp reg $t0 = save[i]
bne $t0, $s5, Exit # go to Exit if save[i] k
Loop: add $s3, $s3, $s4 #i=i+j
add $t1, $s3, $s3 # Temp reg $t1 = 2 * i
6 add $t1, $t1, $t1 # Temp reg $t1 = 4 * i
Instr’s add $t1, $t1, $s6 # $t1 = address of save[i]
lw $t0, 0($t1) # Temp reg $t0 = save[i]
beq $t0, $s5, Loop # go to Loop if save[i] = k
Exit:
The number of instructions executed by this new form of the loop is 5 +
10 6 = 65 Efficiency = 1.15 = 75/65. If 4 i is computed before
the loop, then further efficiency in the loop body is possible.
Do-While Loop
do { Rewrite L1: g = g + A[i];
g = g + A[i]; i = i + j;
i = i + j; if (i != h) goto L1
} while (i != h);
L1: sll $t1, $s3, 2 # $t1 = 4*i
g: $s1 add $t1, $t1, $s5 # $t1 = addr of A
h: $s2 lw $t1, 0($t1) # $t1 = A[i]
i: $s3 add $s1, $s1, $t1 # g = g + A[i]
j: $s4 add $s3, $s3, $s4 # i =i+j
Base of A: $s5 bne $s3, $s2, L1 # go to L1 if i != h
• The conditional branch is the key to decision making
Inequalities
• Programs need to test < and >
• Set on less than instruction
• slt register1, register2, register3
– register1 = (register2 < register3)? 1 : 0;
• Example: if (g < h) goto Less;
g: $s0 slt $t0, $s0, $s1
h: $s1 bne $t0, $0, Less
• slti: useful in for loops if (g >= 1) goto Loop
slti $t0, $s0, 1 # $t0 = 1 if g < 1
beq $t0, $0, Loop # goto Loop if g >= 1
• Unsigned versions: sltu and sltiu
Inequalities
Set on Less Than
A. After the following code executes, what value is in register $7 ?
addiu $5,$0,-25
addiu $6,$0,25
slt $7,$5,$6
Register $7 will be set to 1, because (when the patterns in registers $5 and $6 are
regarded as signed values) $5 < $6.
B. After the following code executes, what value is in register $7 ?
addiu $5,$0,-25
addiu $6,$0,25
sltu $7,$5,$6
Register $7 will be set to 0, because (when the patterns in registers $5 and $6 are
regarded as unsigned values) $5 is not less than $6. If the bit pattern in
register $5 is regarded as unsigned, it looks like a large positive value
Inequalities
Set on Less Than Immediate
The other two set instructions compare an operand register with an immediate value
in the instruction. There is a version for two's complement:
$s and imm contain two's comp. integers
-32768 <= imm <= 32767 ; slti d,s,imm
if ( $s < imm )
d=1
else
d=0
And a version for unsigned integers:
$s and imm contain unsigned integers 0 <= imm <= 32767; sltiu d,s,imm
if ( $s < imm )
d=1
else
d=0
In both, the immediate field of the machine instruction is 16 bits wide. However,
the sltiu instruction can only be used with small integers 0 <= imm <= 32767 (and
another range which is not important for this course.)
Relative Conditions
• == != < <= > >=
• MIPS does not support directly the last four
• Compilers use slt, beq, bne, $zero, and $at
• Pseudoinstructions slt $at, $t1, $t2
• blt $t1, $t2, L # if ($t1 < $t2) go to L bne $at, $zero,
L
slt $at, $t2,
• ble $t1, $t2, L # if ($t1 <= $t2) go to L $t1
beq $at, $zero,
L
slt $at, $t2,
• bgt $t1, $t2, L # if ($t1 > $t2) go to L $t1 bne $at,
$zero, L
slt $at, $t1, $t2
• bge $t1, $t2, L # if ($t1 >= $t2) gobeq
to L
$at, $zero,
L
The C Switch Statement
switch (k) { # f: $s0; g: $s1; h: $s2; i: $s3; j: $s4; k:$s5
case 0: f = i + j; break; bne $s5, $0, L1 # branch k != 0
add $s0, $s3, $s4 #f=i+j
case 1: f = g + h; break;
j Exit # end of case
case 2: f = g - h; break; L1: addi $t0, $s5, -1 # $t0 = k - 1
case 3: f = i - j; break; bne $t0, $0, L2 # branch k != 1
} add $s0, $s1, $s2 #f=g+h
j Exit # end of case
L2: addi $t0, $s5, -2 # $t0 = k - 2
bne $t0, $0, L3 # branch k != 2
sub $s0, $s1, $s2 #f=g-h
if (k==0) f = i + j; j Exit # end of case
L3: addi $t0, $s5, -3 # $t0 = k - 3
else if (k==1) f = g + h;
bne $t0, $0, Exit # branch k != 3
else if (k==2) f = g - h; sub $s0, $s3, $s4 #f=i-j
else if (k==3) f = i - j; Exit:
Jump Tables
# f: $s0; g: $s1; h: $s2; i: $s3; j: $s4; k:$s5
• Jump register instruction # $t2 = 4; $t4 = base address of JT
- jr <register> slt $t3, $s5, $zero # test k < 0
- unconditional branch to bne $t3, $zero, Exit # if so, exit
address contained in register slt $t3, $s5, $t2 # test k < 4
beq $t3, $zero, Exit # if so, exit
add $t1, $s5, $5 # $t1 = 2*k
add $t1, $t1, $t1 # $t1 = 4*k
add $t1, $t1, $t4 # $t1 = &JT[k]
lw $t0, 0($t1) # $t0 = JT[k]
jr $t0 # jump register
L0 L0: add $s0, $s3, $s4 # k == 0
Jump L1 j Exit # break
L1: add $s0, $1, $s2 # k == 1
Table L2 j Exit # break
L2: sub $s0, $s1, $s2 # k == 2
L3 j Exit # break
L3:sub $s0, $s3, $s4 # k == 3
Exit:
Conclusions
• MIPS instruction format – 32 bits
• Assembly: Destination = first operand
• Machine Language: Dest = last operand
• Three MIPS formats: R (arithmetic)
I (immediate)
J (jump)
• Decision instructions – use jump (goto)
• Performance improvement - loop unrolling