Forum: Compiler & IDEs heap vs stack verständnisproblem


von Alexander P. (alexatmikro)


Lesenswert?

hallo,
soweit ich weiß wächst der heap ja 'on top' von data und bss im ram 
richtung obere grenze, während der stack von oben nach unten wächst.

ich habe nun folgendes problem, daß bei mir heap und stack 
zusammenwachsen, obwohl eigentlich genügend seicher da sein müßte.
ich habe keine stark verschachtelten irq handler etc, so daß ich nicht 
von einem übermäßigen stackwachstum ausgehe.
1
  flossy=(float *) malloc(nfl*sizeof(float));
2
  flossx=(float *) malloc(nfl*sizeof(float));
3
4
  for(i=0;i<nfl;i++){
5
    j=i*nmag_+nmag_-1; //we use the last magnet
6
    flossx[i]=datx[j];
7
    flossy[i]=(toty[j]+toty[j-1]+toty[j-2]+toty[j-3]);
8
9
    console__writef(4,0,0,1,flossy[i]);
10
    console__writef(4,0,0,1,flossx[i]);

der wert flossx[i] ist nach dem console_writef aufruf corrupted. wenn 
ich die reihenfolge beim malloc und console__writef umdrehe, dgl. für 
flossx;
wenn ich vorher etwas speicher frei räume gehts ohne probleme.

ich vermute wie gesagt, daß stack und heap irgenwie überlappen.
flogende einstellung im linker script macht mich stutzig:

MEMORY
{
  CODE (rx) : ORIGIN = 0x00100000, LENGTH = 0x00022000
  DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000
  STACK (rw) : ORIGIN = 0x00204000,LENGTH = 0x00000000 /*stack starts 
after data? heap?*/
}

der data bereich ist ca. 16k groß; arm-elf-size sagt mir, daß meine data 
und bss section ca. 4.4 k groß sind; mittels mallinf sehe ich, daß ich 
ca.12k dynamischen speicher belege -> macht in summe ca. 16k die ich in 
data habe?
der stack origin liegt genau drüber?
ist das so überhaupt richtig?

alex

von Alexander P. (alexatmikro)


Lesenswert?

es gibt da diese wunderbare artikelserie (kürzlich erschienen)
http://www.embedded.com/design/opensource/201802580

wenn ich mir den startup code und das linker script anschaue, und 
berücksichtige, daß die ARM eine 'fully descending stack' haben, also 
zur kleineren adresse hin wachsen, würde ich sagen, daß der 
speicheraufbau im besprochenen beispiel so aussieht:
-------ram start (0x0100000)
.data
.bss
.stack
  stack_start

  irq_stack_top

  fiq_stack_top

  ...
  c_stack_top
  stack end
_end=.;
__end=_end;
provide(end=.);


der stack ist decending, d.h. er wächst z.B. für c von c_stack_top in 
richtung fiq_stack_top etc.
die end statements bezeichnen den beginn des heap

der heap liegt also hier doch nach dem stack und wächst nach oben, 
wobei der stack nach unten wächst. dies widerspricht aber meiner ersten 
annahme, daß stack und heap aufeinander zu wachsen...

was ist denn nun richtig?


hier noch der ausschnitt des ld scripts:
    .stack : {
        _stack_start_ = . ;

        . += IRQ_STACK_SIZE;
        . = ALIGN (4);
        _irq_stack_top_ = . ;

        . += FIQ_STACK_SIZE;
        . = ALIGN (4);
        _fiq_stack_top_ = . ;

        . += SVC_STACK_SIZE;
        . = ALIGN (4);
        _svc_stack_top_ = . ;

        . += ABT_STACK_SIZE;
        . = ALIGN (4);
        _abt_stack_top_ = . ;

        . += UND_STACK_SIZE;
        . = ALIGN (4);
        _und_stack_top_ = . ;

        . += C_STACK_SIZE;
        . = ALIGN (4);
        _c_stack_top_ = . ;

        _stack_end_ = .;
    } >RAM

    _end = . ;
    __end = . ;
    PROVIDE(end = .);


und den passenden teil im startup.s:
_cstartup:
    /* Relocate .fastcode section (copy from ROM to RAM) */
    LDR     r0,=__fastcode_load
    LDR     r1,=__fastcode_start
    LDR     r2,=__fastcode_end
1:
    CMP     r1,r2
    LDMLTIA r0!,{r3}
    STMLTIA r1!,{r3}
    BLT     1b


    /* Relocate the .data section (copy from ROM to RAM) */
    LDR     r0,=__data_load
    LDR     r1,=__data_start
    LDR     r2,=_edata
1:
    CMP     r1,r2
    LDMLTIA r0!,{r3}
    STMLTIA r1!,{r3}
    BLT     1b


    /* Clear the .bss section (zero init) */
    LDR     r1,=__bss_start__
    LDR     r2,=__bss_end__
    MOV     r3,#0
1:
    CMP     r1,r2
    STMLTIA r1!,{r3}
    BLT     1b


    /* Fill the .stack section */
    LDR     r1,=__stack_start__
    LDR     r2,=__stack_end__
    LDR     r3,=STACK_FILL
1:
    CMP     r2,r2
    STMLTIA r1!,{r3}
    BLT     1b

    /* Initialize stack pointers for all ARM modes */
    MSR     CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
    LDR     sp,=__irq_stack_top__              /* set the IRQ stack 
pointer */

    MSR     CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
    LDR     sp,=__fiq_stack_top__              /* set the FIQ stack 
pointer */

    MSR     CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
    LDR     sp,=__svc_stack_top__              /* set the SVC stack 
pointer */

    MSR     CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
    LDR     sp,=__abt_stack_top__              /* set the ABT stack 
pointer */

    MSR     CPSR_c,#(UND_MODE | I_BIT | F_BIT)
    LDR     sp,=__und_stack_top__              /* set the UND stack 
pointer */

    MSR     CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
    LDR     sp,=__c_stack_top__                  /* set the C stack 
pointer */

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.