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...