A 2D array
Three rows of four words, one element reached by row and column, and a whole column added up by stepping a row at a time.
Twelve words laid out as three rows of four. The program reads one element by its row and column, and then adds up a whole column, which means stepping through memory a row at a time instead of an element at a time.
Every array up to here was one line of memory. A 2D array is the same line read in rows, and the two
numbers you write in C as grid[row][col] have to be turned into one offset before anything can be
read.
You need to know: the "Arrays, strings and (a0)+" lecture and the "Addressing modes" lecture.
What is new here is the stride, the distance in bytes between one row and the next, which is what
walking a column adds every pass.
The three dc.w lines are one array of twelve words at $2000, and the rows exist only in how they
are written down. row * COLS + col is the element's number in that one line, and doubling it turns
a number of elements into a number of bytes, which is what the address arithmetic actually needs.
d3 comes out at 000000C8, which is 200, the second element of the last row.
Walking a column is the same arithmetic done once. a1 starts at the top of the column and then adds
COLS*2, eight bytes, at every pass: one row further down is one whole row of elements further along
in memory. The assembler works COLS*2 out while assembling, so there is nothing multiplying at run
time. d5 comes out at 000000DE, which is 222, from 2, 20 and 200.
Walking a row would be the same loop with (a1)+ and no add at all, since the elements of a
row sit next to each other and the postincrement mode steps by the size of what it read. A column is
the direction the array is not laid out in, and it costs one instruction per pass to say so.
Try changing move.l #1, d1 to move.l #3, d1. d3 comes out at 00000190, which is 400, and the
column total in d5 at 000001BC, which is 444.