A little help with assembly please

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

I have almost zero avr assembly knowledge. I am trying to use a simple .s file which was for a different compiler, in GCC. The original was this:

_LoadZ::
  movw  Z, r16    ; Load R17:R16 into Z.
  ret

_LoadR0::
  movw  r0, r16   ; Load R17:R16 into R1:R0.
  ret

_ReadELPM::
  elpm r16, Z
  ret 

I changed it to this:

.section .text
.global LoadZ

LoadZ:
  movw  Z, r16    ; Load R17:R16 into Z.
  ret

.section .text
.global LoadR0

LoadR0:
  movw  r0, r16   ; Load R17:R16 into R1:R0.
  ret

.section .text
.global ReadELPM

ReadELPM:
  elpm r16, Z
  ret 

and created this header file:

void LoadZ( unsigned int addr);
void LoadR0(unsigned int addr);
uint8_t _ReadELPM(uint8_t);

when I compile it throws an error that it was expecting a constant at

LoadZ:

I have tried a couple of changes but none worked. thanks

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

Why do you need the header file for?

Do you intend to combine C and asm?

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
LoadZ:
  movw  Z, r16    ; Load R17:R16 into Z.
  ret

try

LoadZ:
  movw  r30, r16    ; Load R17:R16 into Z.
  ret

instead.

And if you intend to combine asm and C you need to follow the ABI.

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

Quote:

And if you intend to combine asm and C you need to follow the ABI.

Yes I do. So would that mean it would have to change to?:

LoadZ:
  movw  r30, r24    ; Load R25:R24 into Z.
  ret 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The easiest way to figure out how to follow the ABI is to start with writing your function in C, with the C function header header looking the way you want. Compile and see what assembler code the compiler emits.

Now write your assembler-implementation doing the interface the same way.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

davidgrm wrote:

Yes I do. So would that mean it would have to change to?:

LoadZ:
  movw  r30, r24    ; Load R25:R24 into Z.
  ret 

Yes that's better. But you can not know if the value in Z is still there if you later call ReadELPM.

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

Quote:

The easiest way to figure out how to follow the ABI is to start with writing your function in C, with the C function header header looking the way you want. Compile and see what assembler code the compiler emits.
Add -save-temps and -fverbose-asm to your compiler options and each file.c will create a file.s in the build directory. What I suspect you will find is that 90% of the time the C compiler does as well as you could so there's very little point in implementing code in .s files unless it's truly uber time critical and you really need to shave a few cycles.

If you want the .s files to be even better the search for "avr-source" at http://spaces.atmel.com

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

Quote:

What I suspect you will find is that 90% of the time the C compiler does as well as you could so there's very little point in implementing code in .s files

I have been trying to get a bootloader to work on an xmega64a3u for about the last week. Those that have no source files work. Those that have source files dont. I did try xboot but did not manage to get it to make using windows. I eventually gave up :https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=137615
I have also being trying to get the one from bandtank to work: https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=137490
I read on this link https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=1111789#1111789 that he had a similar problem so he decided to re-write the sp_driver in C. But he does not use GCC and he does have some assembly stuff in it. I thought I would give it a try on my chip, and then if it works try figure out why the code I have does not.
That bit of assembly is used like this:

    // Load multiple bytes into page buffer
    for (i = 0; i < (FLASH_PAGE_SIZE * 2); i+=2)
    {
        LoadR0(*int_ptr);
        LoadZ(i);
        CPU.CCP = CCP_SPM_gc;
        asm("spm");
        int_ptr++;
    }

So to solve my problem I either have to get somebody who has source for a bootloader in a x64a3u to tell me how they got it to work, or I need to try this code out to see if it works. Any suggestions?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
...
// Load multiple bytes into page buffer
for(i=0; i< 2*FLASH_PAGE_SIZE; i+=2, ++int_ptr) {
    boot_page_fill_safe(*int_ptr, *int_ptr);
} // i

Edit: don't know about CPU. .

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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

Quote:

That bit of assembly is used like this:

In another thread I told you that boot.h contains about 90% of what you need to create a bootloader. I think you'll find that boot_program_page() (or whatever it's called) is as asm macro doing almost exactly the same as that sequence you showed. Start here

http://www.nongnu.org/avr-libc/u...