News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Arnaud

#CPCTelera : SDCC static variable initialization

Started by Arnaud, 20:48, 06 October 17

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Arnaud

Hello,
i meet a problem on the initialization of static variable (with SDCC 3.5.5 and 3.6)

#include <cpctelera.h>
#include "stdio.h"

void Draw() {
    static u8 i = 10;
    printf("%d", i++);
}

void main(void) {
   while (1) {
        Draw();
   }
}


In the function Draw the value of i always start to 0 while i set it to 10 (and the value is incremented).

Then i was thinking SDCC can not initialize local static variable, and i have to use global variable to do this.
But what is curious, is i can see in the assembly the default value set :

;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
    .area _HOME
    .area _GSINIT
    .area _GSFINAL
    .area _GSINIT
;src/main.c:24: static u8 i = 10;
    ld    iy,#_Draw_i_1_87
    ld    0 (iy),#0x0A
;-----------------------


I really don't understand how it works  ???

Thanks,
Arnaud.


Docent

Quote from: Arnaud on 20:48, 06 October 17
Hello,
i meet a problem on the initialization of static variable (with SDCC 3.5.5 and 3.6)

#include <cpctelera.h>
#include "stdio.h"

void Draw() {
    static u8 i = 10;
    printf("%d", i++);
}

void main(void) {
   while (1) {
        Draw();
   }
}


In the function Draw the value of i always start to 0 while i set it to 10 (and the value is incremented).

Then i was thinking SDCC can not initialize local static variable, and i have to use global variable to do this.
But what is curious, is i can see in the assembly the default value set :

;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
    .area _HOME
    .area _GSINIT
    .area _GSFINAL
    .area _GSINIT
;src/main.c:24: static u8 i = 10;
    ld    iy,#_Draw_i_1_87
    ld    0 (iy),#0x0A
;-----------------------


I really don't understand how it works  ???

Thanks,
Arnaud.

Your executable is not linked with crt0.s, which initializes static variables.
As you noticed, sdcc generates initialization for the variable, but it is not called because crt0.s is not included due to --no-std-crt0 compiler option. The result is that the final executable is not linked with crt0.s, which does the initialization of static variables. Your static variable has an uninitialized memory location, which happens to be 0.

Arnaud

Thanks @Docent,

Ok it's intentional with CPCTelera, i use the default compilation arguments.

And one last question what is the gain of the --no-std-crt0 option ? Speed, size, compatibility with cpctelera libraries ?

Docent

Quote from: Arnaud on 06:18, 07 October 17
Thanks @Docent,

Ok it's intentional with CPCTelera, i use the default compilation arguments.

And one last question what is the gain of the --no-std-crt0 option ? Speed, size, compatibility with cpctelera libraries ?

The original crt0.s, included with sdcc is not very well suited for cpc - it removes all interrupt vectors, sets sp to unsuitable address on cpc etc.
The startup code in crt0 is called only once before entering main, so there is no speed penalty when using it and its size is minimal.
I don't see any special gain for cpctelera - actually, it brings issues that you have just found.

Octoate

#4
You can also write your own crt0.s for the CPC that also initialises the static variables. When compiling with the --no-std-crt0, the compiler tries to load an assembled crt0.s. Hans Hansen wrote a crt0 for the CPC years ago and you can read more about how this works in the programming tutorial by CPCMania:
http://www.cpcmania.com/Docs/Programming/Introduction_to_programming_in_SDCC_Compiling_and_testing_a_Hello_World.htm

You can also see that you can provide the putchar routine to the SDCC compiler to enable the stdio. Hmm... maybe I should write a putchar method for the CPC Booster, so you can use it for remote debugging...  :D
--

Docent

#5
Quote from: Octoate on 21:53, 07 October 17
You can also write your own crt0.s for the CPC that also initialises the static variables. When compiling with the --no-std-crt0, the compiler tries to load an assembled crt0.s.

I believe you meant compiling without --no-std-crt0.

Quote from: Octoate on 21:53, 07 October 17
Hans Hansen wrote a crt0 for the CPC years ago and you can read more about how this works in the programming tutorial by CPCMania:
http://www.cpcmania.com/Docs/Programming/Introduction_to_programming_in_SDCC_Compiling_and_testing_a_Hello_World.htm

You can also see that you can provide the putchar routine to the SDCC compiler to enable the stdio. Hmm... maybe I should write a putchar method for the CPC Booster, so you can use it for remote debugging...  :D

Actually, the crt0 you linked above has similar problem - it doesn't initialize global variables and always puts the code at the same start address.

Attached is the minimalistic crt0 for use with cpc - it can be placed anywhere in the memory (with --code-loc compiler option), provides global errno variable and initializes correctly global variables, static variables and jumps into main(). It can be used for programs which don't need to exit back to basic.

I have also other crt0 which initializes stdio and allows to exit to basic via exit() or return from main, but for cpctelera it is probably not needed.

The installation should be trivial (but I haven't tried these steps :)
Copy it to cpctelera/tools/sdcc/lib/z80/crt0.rel and remove  --no-std-crt0 from cfg/build_config.mk and the test project should work correctly.


Powered by SMFPacks Menu Editor Mod