1

screenshot of textbook (The code is an example of adding a list of numbers together and storing the answer using a loop)

100 LDM #0             ; Load 0 into ACC
101 STO total  
102 STO counter  
103 LDR #0             ; Load 0 into IX
104 loop:  
105 LDX number         ; Load the number indexed by IX into ACC
106 ADD total  
107 STO total  
108 INC IX  
109 LDD counter  
110 INC ACC  
111 STO counter  
112 CMP #3  
113 JPN loop  
114 END  
115 number: #5  
116 #7  
117 #3  
118 counter:  
119 total:  

If zero is stored in the index register instead of the address at which "number" is defined, I don't see how the intended number would be loaded into the accumulator.
If line 105, "LDX number" is loading the address into IX, the comment next to it "Load the number indexed by IX into ACC" confuses me. Is it loading the address to IX, and the number at this address into ACC at the same time?

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
Ryan
  • 11
  • 2
  • I added three comments from the text book that seem to be necessary to understand the difference between `LDM`, `LDR` and `LDX`. – Martin Rosenau Aug 21 '23 at 14:55
  • LDR is storing 0 in the alu as the intial number to add to – Dean Van Greunen Aug 21 '23 at 14:55
  • What CPU is that? This is what I see: `LDX: Indexed addressing. Form the address from
    + the contents of the index register. Copy the contents of this calculated address to ACC`. E.g. I suppose _the contents of this calculated address_ means take bytes from the resulting address and put them into accumulator.
    – fukanchik Aug 21 '23 at 15:00
  • @fukanchik It isn't specified what CPU it is, but the textbook had pretty much the same description as you've provided for LDX, my understanding of it was just flawed. – Ryan Aug 22 '23 at 11:00

2 Answers2

3

Is it loading the address to IX, and the number at this address into ACC at the same time?

No:

It adds the address of the element (e.g. variable) specified in the instruction (number) to the value in IX.

The result is an address.

The CPU loads the content of the memory at this address (the sum of the addition) into the register ACC.

In other words:

If the register IX contains the value 5, the instruction loads the 6-th word (on most CPUs: byte) of the variable number into the register ACC.

If you start with IX=0, continue with IX=1 and so on, you first load the first word of number, then the second word and so on ...

Shouldn't line 103 be LDR number instead of #0?

You might do it the following way, too:

...
LDR # number
loop:
LDX 0
...

In this case, IX already contains the "correct" address where to load from so nothing needs to be added in the LDX instruction.

However, the following code would not work:

...
LDR # number
loop:
LDX number
...

This code would load ACC from the address IX+number. If n is the address of the first word of the variable number, the code would load words from 2*n, 2*n+1, 2*n+2 ... instead of n, n+1 and so on ...

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • Thank you, this clears up a lot of the misconceptions I had. I don't know how pertinent this is, but where is the address stored after addition? – Ryan Aug 22 '23 at 10:45
2

In C terms, it is doing the following:

int counter = 0;
int total = 0;
int ix = 0;                    // initialize ix as an index, i.e. start at 0
do {
   total = total + number[ix]; // dereference array "number" at index ix
   ix++;
   counter++;
while ( counter < 3 );

Alternately, as @Martin says, we can use a pointer instead:

int counter = 0;
int total = 0;
int *ix = &number;       // initialize ix as pointer, i.e. to hold address of "number"
do {
   total = total + *ix;  // dereference pointer to fetch numbers
   ix++;
   counter++;
while ( counter < 3 );

On some machines, the pointer approach is shorter/faster because *ix, having no 2nd operand, is shorter to encode and easier to execute than number[ix] — this snippet is inside the loop so (presumed to be) executed repeatedly.  The trade off of larger initialization of ix is worthwhile because that is outside the loop and thus only happens once by comparison.


It would not work to mix the two C approaches, in C you'd get type errors from the compiler, which indicate logic errors in the code.  Assembly won't offer such compile-time errors, but would still be error in logic to mix the pointer initialization outside the loop with array indexing inside the loop.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • I see, thank you for your answer. Seems much clearer in C in spite of only having read some assembly code so far – Ryan Aug 22 '23 at 10:53