I have a program in assembler like this:

        lots of code

.ORG $7000 ;;  (or somewhere) 

atext:   .DB    "this is a test string 1"

         .ALIGN EVEN    

Btext:   .DB    "this is a test string 2"
  1. QUESTION : Assuming the length of text 1 is ODD- Is it possible to ALIGN Btext using some kínd of ALIGN command ( like above). The Atmel Assembler (studío 6.2) says NO - but I wonder....

(Problem easily solved by manually alignment like this:

atext:   .DB    "this is a test string 1",0,0
   //            01234567890123456789012  3 4      

And adding zeroes where needed to align.


I now want to write the text to my serial monitor.

So I do this;

      ldi zh,High (text1)
      ldi zl,LOW (text1)
      push ZH 
      push ZL 
      lsl ZL  
      rol ZH  ;; to ensure LPM later 

WRTE: lpm R16,Z+ ; get byte/data 
      cpi R16,0  
      breq wrte2 
      call output
      rjmp wrte 

      pop zl
      pop zh

Now I wonder: If I use

WRTE: LD   R16,Z+      ; get byte/data /// BAD - DON'T 


What will I get in R16?

  • 1
    \$\begingroup\$ Note that Z indexes the program memory as bytes. The assembler will ensure instruction opcodes are aligned, but for data it doesn't matter. \$\endgroup\$ – Jon Jan 24 '16 at 15:09
  • \$\begingroup\$ Thanks for aligning my code examples - something went terrible wrong during my writing. Kris \$\endgroup\$ – KRIS-Norway Jan 24 '16 at 16:47
  • \$\begingroup\$ What do you want to align Btext too, even, odd, or something else? Why? I think @Jon has answered your question - aligning data doesn't matter as data is byte addressable. Maybe Jon should promote the comment to an answer? \$\endgroup\$ – gbulmer Jan 24 '16 at 18:29
  1. Program memory is 16 bits wide and the program address bus references Words not Bytes, so for example PC address 1 is the second WORD in program memory. The program memory address bus cannot select individual Bytes within a word.

.db automatically puts the text at an 'even' address (padding the string with a zero if necessary) because the Byte equivalent of all program memory addresses is even (the actual address may be odd or even, depending on which WORD is being referenced). Therefore there is no need for an 'ALIGN EVEN' directive.

The LPM instruction routes bits 15-1 of the Z register to program memory address bits 14-0 (referencing up to 32k Words or 64k Bytes), and bit 0 is used to select the lower or upper Byte in the Word. That is why you have to multiply the program address by 2 when putting it into the Z register.

  1. Program memory (ROM) and data memory (RAM) are on separate buses. If you use a regular LD instruction it will access DATA memory (not program memory) and read the contents of RAM at that address. RAM is 8 bits wide and addressed in Bytes, so the address accessed will be exactly what is in the Z register.
  • \$\begingroup\$ Thanks a lot for the comments. The 2'nd paragraph (starting with .db automatically .. ) I did not know. That answers my first question completely. My thought about the 2.nd question was: \$\endgroup\$ – KRIS-Norway Jan 24 '16 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.