Hi

Thanks for the SP, I missed that.
And apparently Atmel Studio also cannot find it, and underlines it with red
error marker.
It does compile, and I have found it in avr/common.h, it's probably a
problem with __AVR_ARCH__ handling by AS...
I guess that's what I get for trusting the IDE:)

I know that just reading SP is not enough, I do also use stack
watermarking. It's just an additional diagnostic information.
Note: SP can also be used to re-mark the unused stack to trace stack usage
over time...
(or mark stack on platforms without .init* sections.)

Note #999:
"the problem is in your code."
This isn't actually my code. My code was written for ARM and looked
something like this:
unsigned int GetStackPointer() {
    volatile register unsigned int sp asm("r13");
    return sp;
}
that someone ported to AVR, and now I'm fixing it... ;)



Üdvözlettel,
Szikra Istvan

On Wed, Nov 8, 2017 at 7:10 PM, Georg-Johann Lay <a...@gjlay.de> wrote:

> Szikra Istvan schrieb:
>
>> Hi all,
>>
>> I have this interesting test case for you guys, and girls.
>>
>> #include <avr/io.h>
>>
>> unsigned int GetStackPointer()
>> {
>>     volatile unsigned int sp = (SPH << 8) | SPL;
>>
>
> There is "SP" for you.  Ne need to hamper with bytes.
>
> uint16_t GetStackPointer (void)
> {
>     return SP;
>
> }
>
>     return sp;
>> }
>>
>> int main(void)
>> {
>>     while(1)
>>     {
>>         PORTA.OUT = GetStackPointer();
>>     }
>> }
>>
>> After building it with Atmel Studio 6.2 (default project settings,
>> -mmcu=atxmega128a4u), AVR8/GNU C Compiler/Linker : 4.8.1 the .lss contains
>> this gem:
>>
>> unsigned int GetStackPointer()
>> {
>>  21a: cf 93        push r28
>>  21c: df 93        push r29
>>  21e: 1f 92        push r1
>>  220: 1f 92        push r1
>>  222: cd b7        in r28, 0x3d ; 61
>>  224: de b7        in r29, 0x3e ; 62
>>     volatile unsigned int sp = (SPH << 8) | SPL;
>>  226: 2e b7        in r18, 0x3e ; 62
>>  228: 8d b7        in r24, 0x3d ; 61
>>  22a: 90 e0        ldi r25, 0x00 ; 0
>>  22c: 92 2b        or r25, r18
>>  22e: 89 83        std Y+1, r24 ; 0x01
>>  230: 9a 83        std Y+2, r25 ; 0x02
>>     return sp;
>>  232: 89 81        ldd r24, Y+1 ; 0x01
>>  234: 9a 81        ldd r25, Y+2 ; 0x02
>> }
>>  236: 0f 90        pop r0
>>  238: 0f 90        pop r0
>>  23a: df 91        pop r29
>>  23c: cf 91        pop r28
>>  23e: 08 95        ret
>>
>> (Atmel Studio 7 (Version: 7.0.1417), gcc version 5.4.0
>> (AVR_8_bit_GNU_Toolchain_3.6.0_1734) does the same.)
>> (If anyone interested I can attach the whole compressed project.)
>>
>
> A working test case is always preferred over binary clump :-)
>
> I'm mostly interested in the push r1, pop r0 pairs.
>> Why? What are they doing? Who puts them there? Can someone "fix" the
>> compiler/binutils?
>>
>
> You used volatile which forces "sp" into the frame of the function.
> As avr-gcc has to set up a frame pointer, this needs to push 2 more
> bytes.  Y is frame pointer and callee-saved here, this explains total
> of 4 bytes of stack usage (not counting return address).
>
> This seems to be a bug for me.
>>
>
> Not to me.
>
> Can someone "fix" the compiler/binutils?
>>
>
> The only bug is in your code:
>
> o Forcing sp onto stack by volatile.
>
> o Using -O1 does not set -fomit-frame-pointer, hence even
>   without the volatile you get a frame pointer.  To get
>   rid of it, use code that doesn't trigger a frame and
>   compile with optimization higher than -O1 and / or with
>   -fomit-frame-pointer.
>
> o Trying to get free stack by reading SP is a broken design.
>   For example, an ISR might consume way more space, which
>   will not be detected by your code.  Consider code like
>   in "mem-check.c" from here:
>
> http://rn-wissen.de/wiki/index.php?title=Speicherverbrauch_
> bestimmen_mit_avr-gcc#Dynamischer_RAM-Verbrauch
>
> AFAIK r1 is the zero reg, and r0 is temp reg, so this should not cause
>> problems, so it's not a critical bug, only optimization issue.
>> (Unnecessary __tmp_reg__ =__zero_reg__ )
>>
>
> As already mentioned, the problem is in your code.
>
> And my optimal solution is
>>     unsigned int GetStackPointer()
>>     {
>>         union { unsigned int w; unsigned char b[2];} w;
>>         w.b[0] = SPL; w.b[1] = SPH;
>>         21a: 8d b7        in r24, 0x3d ; 61
>>         21c: 9e b7        in r25, 0x3e ; 62
>>         return w.w;
>>     }
>>     21e: 08 95        ret
>>
>
> No need for type punning unions, just use "SP" as explained above.
>
> Johann
>
>
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to