avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] push r1, pop r0


From: Szikra Istvan
Subject: Re: [avr-gcc-list] push r1, pop r0
Date: Wed, 8 Nov 2017 13:58:04 +0100

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 <address@hidden> 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
address@hidden
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list


reply via email to

[Prev in Thread] Current Thread [Next in Thread]