Hello everyone,
when i'm mixing c code with assembly for cortex m3 processor, I have something that i do not fully understand.
My code behave like this:
int a=2; int b=3; volatile int r=8; r=assembly_function(a,b); ...
and compliant to the abi standard, a,b are mapped into registers and the r variable into stack. So my dissasebly code for the allocation of r variable is:
0x00000196 2008 MOVS r0,#0x08 0x00000198 9000 STR r0,[sp,#0x00]
Inside my assembly function i want to push something to the stack, for example to pass them into my main function. Lets say i push r3 and r4 so my stack
at the end of my assembly_fuction contains r3,r4 and the r variable before starting the function that now is at r0.
when i come back to my main.c, the return variable is saved into r0 (abi std) so my compiler now update the new value of r variable inside the stack, but in this way:
0x000001A2 9000 STR r0,[sp,#0x00]
So actually overwriting the r3 value.
Why the compiler is not smart enough to know that into the stack was pushed 2 variable so the correct form for update r variable is str,r0, [sp #0x08]?
So my problem is, how can i understand without actually debugging, that where my compiler puts the volatile variable? In this example the flow is very easy, but
in some others i could have many volatile variable with lots of push/pops of the stack. I'd like to know more about this behavior.
Thank you so much
You cannot return data on the stack! If you want to return more then one value, you have to provide pointer parameters (basic C programming).
You mean in R0 pass the memory address where my results are? and what if i want also to pass how many?
ABI std says that parameters passed to to the assembly function, if more than 4, should be done by using the stack.why the return path are not feasible?
At first, it makes not much sense to declare a automatic (stack) variable as volatile. "volatile" tells the compiler, that a variable can be changed without its knowledge.
Second, in order to return more than one value, you have to pass pointers.
Just write a stub of the function you want, compile it and then look at the disassembly.
And, at last, google for "call by reference" "call by value"
you do not understand my question. please read my request carefully before responding.
My main question is very simple: i notices by "disassembly" the code that the c volatile variable is pushed into the stack before the assembly function is called.
In my assembly function, i do some stuff (it is not important what because it is matter to understand and not for a real application) where i push some registers into the stack, and i keep track that i have them in my stack. When i return to the main c code, the compiler pushes the variable r0 into the stack, just because the call is done by:
r=assembly_function(a,b);
and r is volatile.
Doing so, the problem is that i loose the last variable into the stack because it is overwritten by the r after i returned to the c code.
Maybe, the answer could be "when calling a procedure in asm, at the end of it, you must clear the stack as it was in the origin when you called the procedure" or something like this. I do not understand why the compiler do not track the number of pushes, and modify the r variable that is behind my data pushed into asm function and overwrite the last var. or maybe i'm wrong in the way i'm thinking.
It is not a appropriate response reminding me what volatile variable is, just because it is not my request! if this was the problem, google is my friend, i already know!
By the way, thank you.
Sure, the stack pointer _after_ a function call must be the same as _before_. Sorry, I thought this is obvious. Else you would need some kind of technique to tell the compiler.And again, please check for "call by reference" because the thing you try to do, cannot be done, at least not in C.Another thing: "push" does mean: store on stack and reduce the stack pointer.So r0 is _not_ "pushed" after the function call. It is rather stored in its stack location.
BTW: I checked with GCC, and yes (strange to me) "volatile" seems to force the compiler to store the variable on the stack instead of using a register.