Re: push r1, pop r0
Szikra Istvan <[email protected]> Wed, 8 Nov 2017 13:58:04 +0100
| Newsgroups | gmane.comp.hardware.avr.gcc |
|---|---|
| Message-ID | <CAESJyviyQNG9ooHrbS8WD=9dw5kOL=gfM6FnK+wtbW6AeWSZzw@mail.gmail.com> |
Hi all,
I'm writing C++ code, but I made the example a C project. Yeah (void)
I do use stdint.h, stddef.h, stdbool.h I just try to avoid the include hell
for examples. ;)
Note: avr/io.h already includes inttypes.h which includes stdint.h, so I
probably should have used uint16_t.
I use GetStackPointer to get the value of the stack pointer, to calculate
used and free stack space.
inlining the function is better... except when you have to debug your code
;) (and you are unable to place a breakpoint anywhere in AS because
everything is inlined >:( )
> "There is no need to use unions here "
I agree that "the compiler should be able to handle this well."
But it doesn't !
Code:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
static inline uint16_t GetStackPointer(void) {
return (SPH << 8) | SPL;
}
int main(void) {
while(1) {
printf_P(PSTR("SP=%u\r\n"), GetStackPointer());
}
}
Result:
int main(void) {
while(1) {
printf_P(PSTR("SP=%u\r\n"), GetStackPointer());
238: cc ef ldi r28, 0xFC ; 252
23a: d1 e0 ldi r29, 0x01 ; 1
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
static inline uint16_t GetStackPointer(void) {
return (SPH << 8) | SPL;
23c: 2e b7 in r18, 0x3e ; 62
23e: 8d b7 in r24, 0x3d ; 61
}
int main(void) {
while(1) {
printf_P(PSTR("SP=%u\r\n"), GetStackPointer());
* 240: 90 e0 ldi r25, 0x00 ; 0*
* 242: 92 2b or r25, r18*
244: 9f 93 push r25
246: 8f 93 push r24
248: df 93 push r29
24a: cf 93 push r28
24c: 0e 94 2d 01 call 0x25a ; 0x25a <printf_P>
250: 0f 90 pop r0
252: 0f 90 pop r0
254: 0f 90 pop r0
256: 0f 90 pop r0
258: f1 cf rjmp .-30 ; 0x23c <main+0x4>
(This was compiled with -Os
Invoking: AVR/GNU C Compiler : 5.4.0
"C:\Program Files
(x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe"
-x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files
(x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\include" -Os
-ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall
-mmcu=atxmega128a4u -B "C:\Program Files
(x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega128a4u"
-c -std=gnu99 -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o"
".././main.c"
)
So it is 2017, but the compiler still cannot optimize away bitwise or
zero... :(
Here's my version:
int main(void) {
while(1) {
printf_P(PSTR("SP=%u\r\n"), GetStackPointer());
238: cc ef ldi r28, 0xFC ; 252
23a: d1 e0 ldi r29, 0x01 ; 1
//}
static inline uint16_t GetStackPointer(void)
{
union { unsigned int w; unsigned char b[2];} w; /// in 2017 you still
need this to produce optimal asm code :(
w.b[0] = SPL; w.b[1] = SPH;
23c: 8d b7 in r24, 0x3d ; 61
23e: 9e b7 in r25, 0x3e ; 62
return w.w;
}
int main(void) {
while(1) {
printf_P(PSTR("SP=%u\r\n"), GetStackPointer());
240: 9f 93 push r25
242: 8f 93 push r24
244: df 93 push r29
246: cf 93 push r28
248: 0e 94 2b 01 call 0x256 ; 0x256 <printf_P>
24c: 0f 90 pop r0
24e: 0f 90 pop r0
250: 0f 90 pop r0
252: 0f 90 pop r0
254: f3 cf rjmp .-26 ; 0x23c <main+0x4>
Thanks for all your help.
Best regards,
Szikra Istvan
On Wed, Nov 8, 2017 at 11:17 AM, David Brown <[email protected]> wrote:
> On 08/11/17 10:21, Sergey A. Borshch wrote:
> > On 08.11.2017 11:03, David Brown wrote:
> >> (Also, if you are writing C rather
> >> than C++, your function declaration is not correct.) The sensible way
> >> to write this is:
> >>
> >> static inline uint16_t GetStackPointer(void)
> >> {
> >> return (SPH << 8) | SPL;
> >> }
> > It's not correct declaration too. Function name clearly states that it
> > is returning pointer, so it should return... pointer:
> > static inline void * GetStackPointer(void)
> > {
> > return (void *)((SPH << 8) | SPL);
> > }
> >
>
> I viewed it more as meaning "get the contents of the stack pointer
> register", rather than "get the pointer to the current top-of-stack".
> That is up to the OP, to choose what he wants here.
>
> My point was merely that in C (but not C++), a function taking no
> parameters should be declared with a "void" parameter list. Omitting
> that is allowed (and the code generated is identical), but it is an
> obsolete feature in C. If the OP was writing C++, then it is fine.
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>
_______________________________________________
AVR-GCC-list mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list