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.