9/17/02 Tue
The variables in C are abstraction of storage where values can be assigned or read. In assembly there are two kinds of storage: register and memory. Register is fast storage that can be accessed for arithmetic directly, but has limited number of units depending on the architecture. For example, MIPS has 32 registers. Memory allows to keep much larger storage space than registers, but cannot be used for arithmetic operations directly. In stead, data in the memory is loaded to the registers before the arithmetic operations. Variables have their associated types whereas there are no explicit types for registers and memory. The types are implied in the instruction  an instruction uses word type or others uses double word.

C 
Assembly 
Storage 
int i, n; 
Register: $0, $1, ..., $31 
Arithmetic operations in MIPS assembly takes two source registers and one destination register with the following form:
<Opname> <dest_reg> , <source_reg1> , <source_reg2>
For example,
ADD $s1, $s2, $s3 # $s1: a, $s2: b, $s3: c, a = b + c
When an expression has more than two arithmetic operations, then it can be calculated in multiple instructions possibly with temporary registers.
For a = b + c  d,
ADD $s1, $s2, $s3 # $s1: a, $s2: b, $s3: c, $s4: d
SUB $s1, $s1, $s4
For a = (b + c)  (d + e),
ADD $s1, $s2, $s3 # $s1: a, $s2: b, $s3: c, $s4: d, $s5: e
ADD $t1, $s4, $s5
SUB $s1, $s1, $t1
Register zero ($0) is hardwired to zero and has always zero value. And memory operations can be expressed with general operations by using register zero.
For a = b, ADD $s1, $s2, $0
For a = b, SUB $s1, $0, $s2
Instructions that try to modify register zero do nothing because the register zero cannot be modified.
ADD $0, $s1, $0
<Opname> <reg1> , <offset> ( <reg2> )
LW $s1, 4 ($s2) # load a word to $s1 from the source memory. The source memory is 4bytes after the location $s2 points to.
SW $s1, 4 ($s2) # store a word from $s1 to the memory which is 4bytes after the location $s2 points to.
An immediate value is a constant that is embedded in an instruction. This allows simple integer values can be used for operations without load.
ADDI $s1, $s2, 1 # a = b + 1
SLL $s1, $s2, 4: shift the value in the register $s2 four bits to the left and write it to the register $s1. This multiplies $s2 with 16.
SRL $s1, $s2, 2: shift the value in the register $s2 two bits to the right and write it to the register $s1. This divides $s2 by 4.
Shift operations substitutes multiplication and division when an operand is a power of two (2, 4, 8, etc) and faster.
Can we write any programs with assembly with the instructions we learned? We need control flow instructions to implement a branch and a loop.
In C, there are several control flow instructions, but all of them can be expressed using if and goto. In MIPS assembly, there are conditional branches (beq/bne) and an unconditional jump ( j ).
Original constructs  Using only if and goto  Assembly  
if 
if (a == b) x = y + z; 
if (a != b) goto L1; x = y + z; L1: 
BNE $s1, $s2, L1 ADD $t1, $t2, $t3 L1: 
if else 
if (a == b) x = y + z; else x = y  z; 
if (a != b) goto L1; x = y + z; goto L2; L1:x = y  z; L2: 
BNE $s1, $s2, L1 ADD $t1, $t2, $t3 J L2 L1:SUB $t1, $t2, $t3 L2: 
if else if else 
if (a == b) x = y + z; else if (c == d) x = y  z; else x = y + 1; 
if (a != b) goto L1; x = y + z; goto L3; L1:if (c != d) goto L2; x = y  z; goto L3; L2:x = y + 1; L3: 
BNE $s1, $s2, L1 ADD $t1, $t2, $t3 J L3 L1:BNE $s3, $s4, L2 SUB $t1, $t2, $t3 J L3 L2:ADDI $t1, $t2, 1 L3: 
do while 
do a = a  1; while (a != 0); 
L1:a = a  1; if (a != 0) goto L1; 
L1:ADDI $s1,
$s1, 1 BNE $s1, $0, L1 
while 
while (a != 0) a = a  1; 
L1:if (a == 0)
goto L2; a = a  1; if (a != 0) goto L1; L2: 
L1:BEQ
$s1, $0, L2 ADDI $s1, $s1, 1 BNE Ss1, $0, L1 L2: 
What if we need to evaluate inequality such as <, >, <= or >=?
We can use SLT.
SLT $t1, $s1, $s2 # $t1 is set to 1 if $s1 < $s2. Otherwise it is set to zero.
Original constructs  Assembly  
== 
if (a == b) x = y + z; 
BNE $s1, $s2, L1 ADD $t1, $t2, $t3 L1: 
!= 
if (a != b) x = y + z; 
BEQ $s1, $s2, L1 ADD $t1, $t2, $t3 L1: 
< 
if (a < b) x = y + z; 
SLT $t4, $s1, $s2 BEQ $t4, $0, L1 ADD $t1, $t2, $t3 L1: 
<= 
if (a <= b) x = y + z; 
SLT $t4, $s2, $s1 BNE $t4, $0, L1 ADD $t1, $t2, $t3 L1: 
int A[100];
int main(void) { int i, sum; fill_the_array(A, 100); sum = 0; i = 100; do { i = i  1; sum += A[i]; } while (i != 0); /* The sum is in 'sum' */
}
Intermediate C code
int A[100];
int main(void) { int i, sum; fill_the_array(A, 100); sum = 0; /* sum: $s1 */ i = 100; /* i: $s2 */ L1: i = i  1; sum += A[i]; /* A: $s3 */ if (i != 0) goto L1; /* The sum is in 'sum' */
}
Assembly code
ADD $s1, $0, $0 ADDI $s2, $0, 100 ADDI $s3, $s3, 400 L1: ADDI $s2, $s2, 1
___________________ LW $t1, 0 ($s3) ADD $s1, $s1, $t1
___________________