Accessing an array in asm

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

Hi
I have a buffer that is allocated in C and a pointer to the current position in the buffer, also allocated in C. I want to set the pointer to the first address of the buffer in my assembler file, but I am out of ideas on how to do that...

This is what I want to do:

In the C-code:
---
uint8_t Buffer[64];
uint8_t *pCurrent;
---

In the assmebler file:
---
ldi R30, LOWER_BYTE(Buffer)
ldi R31, HIGHER_BYTE(Buffer)
sts R30, pCurrent
sta R31, pCurrent+1
---

Best regards,
COLA

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

Not really sure what you are trying to achieve - maybe write in C what it is you want to do? (of course if you did that you could simply compile, see what the C compiler generated and then put that into your Asm code - of course, if you did that you might as well not bother with the Asm at all as the C would work just as well!)

But I can't help thinking that once you have the address of 'Buffer' into R30:R31 (aka 'Z') that if you want to load from the array you probably want to use "LD Rn, Z" or even "LD Rn, Z+" and if you want to store to the array "ST Z,Rn" or "ST Z+, Rn"

Cliff

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

Hi All,

For the sake of us neophytes, could someone explain what tool we have that converts C into assembly; and give an example of how to use it.
Hopefully something compatible with the following tools:
avrdude-5.4
gcc-4.2.0
avr-libc-1.4.6

Thanks,
Sky

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

GCC converts all of its C code into assembly as one of the intermediate steps to generating the final binary.

In fact, with the default makefile provided by WinAVR, you easily get an assembly listing of the complete program, with the original C source code interspersed, every time you run make all. It's in the .lss file.

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

Well, maybe I was a little unclear about my question. What I want to do is this (in C):

uint8_7 Buffer[64];
uint8_t *pCurrent;  // the current position in the buffer, where data should be put

pCurrent = Buffer;  // <-

I have compiled the C-code for that once and it looked like this:

ldi R30, 0x123
ldi R31, 0x124
sts R30, pCurrent
sts R30, pCurrent+1

As you can see the 0x123 is the lower byte of the address to Buffer, and 0x124 is the upper byte of the address. But I can not write an absolute address in assembler, since the position of the Buffer in memory could change between builds. So my problem is to get the compiler to extract the lower and higher byte from the Buffer-address when building the project.
For other compilers the LOWER(word) and HIGHER(word) or something like it will get the low and high byte of the word, but I can not find out how to do it when using winavr. Right now I'm cheating by doing this:

-- file.c --
uint8_t Buffer[64];
uint8_t *pBuffer = Buffer;
uint8_t *pCurrent;
----

-- file_asm.s --
ldi R30, pBuffer
ldi R31, pBuffer+1
sts R30, pCurrent
sts R30, pCurrent+1

Sure, it works and memory is not an issue so I could leave it like that, but I want to know! :)

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

I just copied your code into a eric.c file and then using an Mfile generated Makefile I just used "make eric.s" and the salient bit from that was:

	ldi r24,lo8(3)
	ldi r25,hi8(3)

So I guess there's your answer, the macros you want to use are lo8() and hi8()

But I'm still unclear as to why the code needs to be written in Asm? Won't the C compiler do just as good a job as you will anyway?

Cliff

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

Ah thank you Cliff, it worked.

The code is part of a time critical ISR, and I would not want to write time critical parts that are dependent on compiler optimization to finish before its deadline. And what happens if you change the compiler or optimization-level? With the time critical code written in assembler I have total control of the number of clock cyckles WCET is, so I can even debug using no optimization at all making it a little easier to step through, which is nice :)