Pwelb
Pwelb

Reputation: 115

How do low() and high() functions work in AVR

I am trying to understand some assembly code, and I'm not understanding how some values are found. If the code:

ldi     ZL, low(2*table)        
ldi     ZH, high(2*table)

Is executed with the table:

table:      .db     32, 34, 36, 37, 39, 41, 43, 45, 46, 48, 50, 52, 54, 55, 57, 59, 61, 63, 64, 66

And I am looking at the element 5 of the table, 41.

What do the ldi operators do in this example? After the first ldi is executed, 14 is stored in the SRAM at the ZL location, but why is it 14?

After the second one is executed, 02 is stored at the ZH location.

Upvotes: 0

Views: 2477

Answers (1)

Andy Preston
Andy Preston

Reputation: 772

Flash memory is "word addressed", the assembler label table gives the table's address in words. The * 2 gives the correct address in bytes. I prefer to use << 1 rather than * 2 as, to me, this makes things clearer.

To actually access the 5th Element of the table you would do something like this:

    ldi ZL, low(table << 1)  ; (or you could use `table * 2`)
    ldi ZH, high(table << 1) ; Z Register points to start of table
    ldi r25, 5               ; register r25 contains required offset in table
    clr r1                   ; (I always have r1 set to zero all the time)
    add ZL, r25              ; add offset to base pointer
    adc ZH, r1               ; if the low byte of the Z register "pointer"
                             ; overflowed, add the carry flag to the high byte
    lpm r24, Z               ; read the 5th element of the table into r24

This is also covered in the following SO questions:

Upvotes: 1

Related Questions