int x[100];
short y[100];
byte z[100];
int i;
short j;
byte k;
class List
{
int value1;
short value2;
List next
}
List head; (head contains the start of a linked list,
assume the linked list has been created and is
not empty)
x[i + j] = y[i * k] + z[j / k] + head.value1 + head.next.value2;
|
(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)
(3) Add them as int
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
(5) Add to sum
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
(7) Add to sum
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...