Re: push r1, pop r0
Szikra Istvan <[email protected]> Thu, 9 Nov 2017 04:57:38 +0100
| Newsgroups | gmane.comp.hardware.avr.gcc |
|---|---|
| Message-ID | <CAESJyviigqGj5OztWt6=xLj8A-dWUW5MrudRrhWh-8n7z4mcDQ@mail.gmail.com> |
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 <[email protected]> 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
[email protected]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list