I am trying to write some code for an ATmega16. I have been using the avra (version 1.4.2) under FreeBSD 12.2-RELEASE. I have the following in my code segment:
helloStr: .db "Hello World\0"
It is my understanding that the bytes of the characters should be contiguous. However when I look at the object file produced I see the following (I am assembling the code using the command avra main.asm):
00000190: 0000 3600 0000 2a65 4800 0039 0000 002b ..6...*eH..9...+
000001a0: 6c6c 0000 3900 0000 2c20 6f00 0039 0000 ll..9..., o..9..
000001b0: 002d 6f57 0000 3900 0000 2e6c 7200 0039 .-oW..9....lr..9
000001c0: 0000 002f 5c64 0000 3900 0000 3000 3000 .../\d..9...0.0.
000001d0: 0039 0000 0031 e2fa 0000 3d00 0000 32e0 .9...1....=...2.
Notice on the right that the characters aren't consecutive. I'm looking at the .obj file that avra is producing. When I try to run the code it seems to confirm my suspensions that the character bytes are not being stored contiguously as I get mostly garbage on the display with some of the correct characters, but spaced far too far apart. I don't think there is anything wrong with my display routine (The LCD display code will display a character correctly if I remove the looping code and store the character directly in r16 using ldi r16, 'H', for example.):
WRITE_TO_LCD:
push r16
push r17
START_WRITE_TO_LCD:
lpm r16, Z+
ldi r17, 0b0
cp r16, r17 ; Have we hit the null byte?
breq END_WRITE_TO_LCD
;; Output character command.
out PortA, r16
ldi r16, low(registerSelect) ; Set RS control signal
out PortC, r16
;; Set E and RS control siginals.
ldi r16, (low(registerSelect) | low(enable))
out PortC, r16
ldi r16, low(registerSelect) ; Clear E control signal
out PortC, r16
jmp START_WRITE_TO_LCD
END_WRITE_TO_LCD:
pop r17
pop r16
ret
I'm loading Z with:
ldi r31, low(helloStr)
ldi r30, high(helloStr)
before I call WRITE_TO_LCD. I'm not sure if low to r31 and high to r30 is the right way around but I have also tried the other way. I also read that the memory is addressed using 2 byte words so I should use 2*helloStr. I've tried doing that too. Maybe these details that I have just mentioned aren't right in the code I've shown here but I've tried all the permutations and I don't think it's the problem (as evidenced by the out put on the LCD and what I can see in the hex editor.)
Also I have define helloStr after my interrupt vector. If I place it before the interrupt vector I can't seem to see any evidence of it in the .obj file and the output on the LCD is different when I actually run it. I assume that this has something to do with the interrupt vector needing to be the first thing in memory or something like that. But I would have though that it would have still shown up in the code and the handling of interrupts would be messed up.
Anyway the thing I'm really interested in is getting a contiguous string in flash so I can loop over it.
If anyone has any idea what I might be doing wrong I would very much appreciate your input.