CS255 Syllabus

### A comprehensive example in Operand Manipulation

• Suppose we have the following variables defined:
```     int   x[100];
short y[100];
byte  z[100];

int   i;
short j;
byte  k;

class List
{
int   value1;
short value2;
List next
}

assume the linked list has been created and is
not empty)
```

• Write an equivalent assembler program for:
```   x[i + j] = y[i * k] + z[j / k] + head.value1 + head.next.value2;
```

• How to compute the expression:

 We perform all computations in the high accuracy available --- this is int (32 bits) in M68000 So we will make sure all values fetched to a data register for computation are int Get y[i * k] and convert to int if necessary Get z[j / k] and convert to int if necessary Add them (as int) Get head.value1 and convert to int if necessary Add to sum (as int) Get head.next.value2 and convert to int if necessary Add to sum (as int) Get the address of x[i + j] Put the value of the sum computed previously in that address.

• The following is the solution:
```  (1) Get y[i * k] and convert to int if necessary:

MOVEA.L #y, A0		A0 = base address of array "y"

MOVE.L  i, D0		D0 = i (i is int, so use 32 bits)
MOVE.B  k, D1		D1 = k (k is byte, so use 8 bits)

*** We can't muultiply i + k yet !!
*** MULS always uses short (16 bits) operands
*** D1 (= k) is 8 bits --- wrong data types !

EXT.W   D1		D1 = k (as short --- 16 bits)

*** now we can compute i * k !

MULS   D1, D0		D0 = i * k (32 bits).
It's an index, NOT offset

MULS   #2, D0		Because elements in array "y" are short,
we multiply by 2 to get the offset

MOVE.W 0(A0,D0), D7     D7 = y[i * k] (as short --- 16 bits)

*** Convert the value to int (32 bits) for computation

EXT.L   D7              D7 = y[i * k] (as int --- 32 bits)

(2) Get z[j / k] and convert to int if necessary:

MOVEA.L #z, A0		A0 = base address of array "z"
MOVE.W  j, D0		D0 = j (16 bits)
MOVE.B  k, D1		D1 = k (8 bits)

*** Can't divide j / k yet !
*** Divident must be 32 bits !!!
*** Divider  must be 16 bits !!!

EXT.L   D0              Convert divident into int (32 bits)
EXT.W   D1		Convert divider  into short (16 bits)

*** now we can divide j / k !

DIVS    D1, D0		D0 = j / k (16 bits).
It is an index, NOT offset

MULS   #1, D0		Because elements in array "z" are bytes,
we multiply by 1 to get the offset
(You can omit this instruction....)

MOVE.B 0(A0,D0), D6     D6 = z[j / k] (in 8 bits)

*** Convert the value to int (32 bits) for computation

EXT.W  D6               D6 = z[j / k] (in 16 bits)
EXT.L  D6               D6 = z[j / k] (in 32 bits)

ADD.L   D6, D7		D7 (32 bits) = y[i * k] + z[j / k]

+++ NOTE: Do NOT use D7 in any computation !
+++ You need it later !!!

(4) Get head.value1 and convert to int if necessary:

MOVEA.L  head, A0	A0 points to the first element of list
MOVE.L   (A0), D0	D0 contains the value head.value1 as int

ADD.L    D0, D7		D7 = y[i * k] + z[j / k] + head.value1

(6) Get head.next.value2  and convert to int if necessary:

MOVEA.L  head, A0       A0 points to the first element of list
MOVEA.L  6(A0), A0      A0 points to the second element of list
MOVE.W   4(A0), D0      D0 contains the value head.next.value2 as short

*** Convert the value to int (32 bits) for computation

EXT.L   D0              D0 contains the value head.next.value2 as int

ADD.L    D0, D7         D7 = y[i * k] + z[j / k] + head.value1 + head.next.value2 as int

*** To store to memory, we need to
*** compute the address of the variable first

(8) Get the address of x[i + j]:

MOVEA.L #x, A0		A0 = base address of array "x"

MOVE.L  i, D0		D0 = i (32 bits)
MOVE.W  j, D1		D1 = j (16 bits)

*** Can't add i + j yet because:
***   i is int
***   j is short
*** Convert to same type !!!

EXT.L   D1		D1 = j (32  bits)

*** now we can add i + j !

ADD.L   D1, D0		D0 = i + j (32 bits)
This is an index, NOT offset

MULS   #4, D0		Because elements in array "x" are int,
we multiply by 4 to get the offset

*** Now 0(A0, D0) is the address of
*** variable x[i + j]

(9) Put the value of the sum computed previously in 0(A0, D0):

MOVE.L  D7, 0(A0, D0)

```
DONE... finally...

Now take a look back at the mess we made just to do the simple looking addition "x[i + j] = y[i * k] + z[j / k] + head.value1 + head.next.value2"..... Almost a FULL PAGE of assembler code...