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 <da...@westcontrol.com> 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
> AVR-GCC-list@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to