RAM addressing issue (please check this out)

so i want to use specific places in the SRAM of my arduino (AVR) using assembly . for example i want to use all the ram addresses from a to b for an array of mine in assembly . the thing is how can i know if that address is used by the C program . i am using inline assembly with the usual arduino language . so how can i know if the space i am addressing is used or not .

i dont want to use directives like .byte or stuff like that . i just want to use number addresses

The short answer is, don't. There is no need to do it.

There is a long answer. It is possible. If you read about 5000 pages of assembler documentation, you might figure it out. Basically, you need to create instructions to the compiler/assembler, to reserve a specific range of memory for you. I know exactly how this is done on some other platforms, never tried it on the arduino, but I believe it is possible.

Why not allocate the space for the array in C code and then you should not have a problem ?

...R

Robin2 , i tried that . the pointer seems to give the first value of the array , but then when i increment the address it starts providing random useless values

How much are you incrementing the pointer by ?

amine2: Robin2 , i tried that . the pointer seems to give the first value of the array , but then when i increment the address it starts providing random useless values

And what you tried is a secret, is it?

amine2: Robin2 , i tried that . the pointer seems to give the first value of the array , but then when i increment the address it starts providing random useless values

Then you must be doing something wrong. The addressing system is brutally simple (i.e. simple and unforgiving)

...R

amine2: Robin2 , i tried that . the pointer seems to give the first value of the array , but then when i increment the address it starts providing random useless values

If that is true then you are doing something very wrong, and you should figure out what that is, rather than creating a new more complex method that will likely lead to other problems.

Regards, Ray L.

that is just a little example , storing values 48 to 52 in addresses of array elements ptr[0] to ptr[4]
then print the values , it should return
48
49
50
51
52
but it does not !

void setup() {
Serial.begin(9600);
byte ptr[5];
__asm__ __volatile__ (
"ldi r16,48\n\t"
"ST X+,r16\n\t"
"inc r16\n\t"
"ST X+,r16\n\t"
"inc r16\n\t"
"ST X+,r16\n\t"
"inc r16\n\t"
"ST X+,r16\n\t"
"inc r16\n\t"
"ST X,r16\n\t"
::"x" (&ptr[0]):"r16"
);
for(byte x=0;x<5;x++) Serial.println((int)x);
}

Moderator edit: Tags corrected

Robin2: Why not allocate the space for the array in C code and then you should not have a problem ?

amine2: Robin2 , i tried that . the pointer seems to give the first value of the array , but then when i increment the address it starts providing random useless values

Show the C code, not the assembler code. This all sounds like a Bad Idea to me.

@amine2. can you explain how the assembler code in Reply #8 is supposed to do ? (to save me having to look it all up).

but it does not !

What does it do ? - that may provide a clue to the problem.

...R

ok here is the deal . the client wants this to be done an an arduino . an arduino uno that has a CPU frequency of 16Mhz . the program is about some waves at a very high frequency to communicate with a machine . at first i though this would be impossible at just 16mhz using C or C++ since you cant tell what the compiler would put in the coda that would just waste time . the cos and sine wave are so time critical that 4 or 5 clocks even at 16mhz ruin the whole thing . now reading data off of a C array in assembly needs some work . all i want is to know the first address then just increment . i usually work with assembly and C , but the client wants arduino at 16mhz . knowing the first address of bytes in sram then just incrementing seems much faster . the example i did put there just shows a little example .

now this worked as a standalone program , and everything went fine , since i coded the whole thing and kept tweeking the range on the SRAM untill i was lucky enough for it to work . the SRAM is packed with critical data . so placing something at a relatively random range of addresses seems impossible but it worked (btw i need 721 bytes only) . the thing is the client wants this to work with any program . something like a library or something wich means i have no idea what he is placing in the RAM and where . and since the compiler packs everything togeather it just seems impossible .

now what i need is help for me to declare the 721 byte space in C , then a method to get the addresses in a timing less than 2 or 3 cycles per byte

byte storage[721];

Isn't continuous? I think, yes.

i did try that . i put &storage[0] in register pair Z for example . now the first value is correct. when i increment Z a couple of times it starts returning garbage

The problem must somewhere else. Code? BTW, if you want to debug ASM, it is good to use Atmel Studio. It is for free.

  1. Inline assembler ptr input incorrectly.
  2. For loop will not print out contents of ptr array unless ptr array is used.
void func() {
  Serial.begin(9600);
  byte ptr[5];

  __asm__ __volatile__ (
    "ldi r16,48 \n\t"
    "ST X+,r16  \n\t"
    "inc r16    \n\t"
    "ST X+,r16  \n\t"
    "inc r16    \n\t"
    "ST X+,r16  \n\t"
    "inc r16    \n\t"
    "ST X+,r16  \n\t"
    "inc r16    \n\t"
    "ST X,r16   \n\t"
    ::"x" (ptr) : "r16"
  );
  for (byte x=0; x<5; x++)
    Serial.println((int)ptr[x]);
}

amine2:
now what i need is help for me to declare the 721 byte space in C , then a method to get the addresses in a timing less than 2 or 3 cycles per byte

If you answer the questions in Reply #10 I may be able to help.

…R

thank you very much robin, guys . i found a solution to the problem .
for you to address a full array and increment the address to get the rest of the values using assembly .
you must declare the array as volatile then use a pointer for the address .

example :

volatile byte tab[10];
volatile void* pointer_to_tab = tab;

asm volatile( … : : “x” (ptr_to_tab): ); ← this would get the correct data on register pair X then you can use it correctly

or you can just do this asm volatile( … : : “x” (tab): );

amine2: i found a solution to the problem .

Good to hear.

Please post a short complete program that demonstrates what you have discovered. It will be useful for future reference.

...R