0

I am studying for an exam in microprocessors and this example question has come up:

the question

In summary of it, there is an array in program memory after the code:

array: .db 11,12,13,14,15,16,17,18,19,20

and in the code the pointer is loaded as:

ldi ZL, low(array<<1);

My question is why that shift by 1 is present in the code I was given. In my mind the label "array" should point right at the byte of memory that contains the number 11. Shifting left by 1 would multiply by 2, if I understand it correctly. Wouldn't that throw it way off? Is the code I was given just wrong or am I not understanding something?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    See also [this answer](https://stackoverflow.com/a/19307139/547981) especially the note about `avr-as`. – Jester Dec 13 '19 at 14:46
  • Include enough code in the actual question for this to make sense, not just as part of an image. Apparently the key is that we want to use Z as a pointer for `lpm` (load program memory) instead of the usual data memory. – Peter Cordes Dec 13 '19 at 18:58
  • @Jester: This looks like a duplicate (`*2` is the same as `<<1`, done for the same `lpm` reason). I don't understand why this behaviour would ever be useful; do labels work correctly for labels in data sections? Or is there something else you can do with label addresses where you want them divided by 2? – Peter Cordes Dec 13 '19 at 19:04
  • BTW, the text part of the "solution" in the image is wrong. It's not `0x01010101` (a 32-bit number in hex), it's `0b01010101` (an 8-bit number in binary). The source code has it correct: `0x55`. And yes, `x & mask == mask` is how you check that *all* the bits of interest are set. (You could probably do this more efficiently by adding a constant that sets the carry flag if all the mask bits are set, otherwise not. Then use `adc` instead of a branch over an `inc`) – Peter Cordes Dec 13 '19 at 19:59

1 Answers1

0

From the description of LPM:

The program memory is organized in 16 bit words while the Z pointer is a byte address.

So the shift is done to convert from a word address to a byte address.

Michael
  • 57,169
  • 9
  • 80
  • 125
  • I think I get it... so because the program memory is addressed in 16 bit divisions there are only half the number of addressable words in it compared to if it were byte addressed... so multiplying by 2 directs LDI to the correct location in program memory because it assumes everything is byte addressed. – nickhansenrf Dec 13 '19 at 14:58