Trouble translating Assembler directives (Atmel -> GNU)

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

Noob here, learning Assembly.

 

I'm trying to use code ROM data storage on an ATmega328p (Arduino) but I can't get it to work.

This is what I have so far:

#define __SFR_OFFSET    0
#include <avr/io.h>

.equ    RAM_BUF,    0x0140              ; The SRAM location the string needs to be moved to.

; Initialisation
        ldi     ZH,     hi8(STRING)
        ldi     ZL,     lo8(STRING)
        ldi     XH,     hi8(RAM_BUF)
        ldi     XL,     lo8(RAM_BUF)

; Main program
LOOP:   lpm     r20,    Z+
        cpi     r20,    0
        breq    STOP
        st      X+,     r20
        rjmp    LOOP
STOP:   rjmp    STOP

; Fixed data storage
.data
STRING: .asciz  "Hello, World!\n"

The code compiles without error, but the string never gets loaded. Instead R20 gets the value 0xFF every time and thus the LOOP never ends as well.

I am following the Mazidi book "AVR in assembly and C" so only have Atmel assembly code as examples.

The GNU-AS manual is very terse about directives and my Google Fu is failing me.

 

For what its worth, I tried setting the Z register with

        ldi     ZH,     hi8(STRING << 1)

But that produces Error: invalid operands (.data and *ABS* sections) for `<<'

 

Can anyone point me in the direction of resources for translating Atmel directives to GNU?

 

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to use code ROM data storage on an ATmega328p ...

; Fixed data storage
.data
STRING: .asciz  "Hello, World!\n"

 

".data" is explicitly a RAM section.  if you want the string to be in flash, leave that line out (or explicitly use a flash section like ".section .progmem")

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to mult all the LPM addresses by 2, such as

 

hi8(STRING*2)
  ldi     ZL,     lo8(STRING*2)

I am following the Mazidi book "AVR in assembly and C" so only have Atmel assembly code as examples.

That explains it! 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Wed. Jul 24, 2019 - 11:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One thing you can do (easliy) in avr-as that is not so simple in Atmel Asm is simply make use of C's _do_copy_data() so if you have the RAM for it you can just have the data copied out to RAM anyway. In fact it's easiest just to add a .c file to the project:

char text[] = "Hello world";

and the default action of this is that the data "Hello world" is copied out to a RAM location labelled "text:" anyway. Then you just LD from that.

 

But a bit like PROGMEM/_flash in C, if the strings are "const" it may be better to keep them in flash alone. Of course you can use C for that too:

const __flash char text[] = "Hello world";

then "text:" (*2) could be loaded into Z and LPM'd

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your answers!

 

westfw wrote:

".data" is explicitly a RAM section.  if you want the string to be in flash, leave that line out (or explicitly use a flash section like ".section .progmem")

Just leaving the ".data" line out fixed it (at least for simple examples like this).

Must have overlooked the RAM bit in the docs I read.

 

@avrcandles: the first half of the book is Assembly only and the second half compares Assembly with C. They are not combined in this book smiley 

 

@clawson: I think I will stick to learning the basics for now, already challenging enough lol