This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Locating 2 parameters at the same address

I am using an 8051 (C51/BL51) with no off-chip memory. I have two functions with parameters:

void Detect( U8 iLed )

and

static U8 INHSampleHandler( U16 u16Sample )


Now I understand that Keil will allocate a variable (in DATA) for these. The problem seems to be that the locator is using the same memory location for both. I cannot understand why.

Below are excerpts from the scratchpad showing 2 "D:0026H". These are the only places these symbols are declared. Any ideas what I'm doing wrong?

Thanks,
Jeff

BL51 BANKED LINKER/LOCATER V5.12              07/14/2011  09:36:23  PAGE 1


BL51 BANKED LINKER/LOCATER V5.12, INVOKED BY:
Z:\TOOLS\SOFTWARE\KEIL\BL51.EXE Z:\Software\FB_CPU_Init.obj,
>> Z:\Software\Settings.obj, Z:\Software\Glo
>> bals.obj, Z:\Software\Devices\Clock.obj, Z:\ 
>> Software\Devices\Flash.obj, Z:\Software\Devices\HMI.obj
>> , Z:\Software\Devices\INH.obj, Z:\ 
>> Software\Devices\ADC.obj, Z:\Software\Devices\Timer.obj, Z
>> :\Software\Builds\TestINH - 06-00039-21-09\Main.obj
>> , Z:\Software\Test\Test_Button.obj, Z:\So
>> ftware\Builds\TestINH - 06-00039-21-09\Version.obj TO Z:\ 
>> Software\Builds\TestINH - 06-00039-21-09\06-00039-21-09-xx.wsp
>>  RS (256) PL (68) PW (78) XDATA (?XD?SETTINGS (0X0)) CODE (?CO?VERSION (0X7
>> FC0))


MEMORY MODEL: SMALL

Deleted for brevity

  -------         PROC          _INHSAMPLEHANDLER
  D:0026H         SYMBOL        u16Sample
  C:0BF1H         LINE#         150
  C:0BF5H         LINE#         151
  C:0BF5H         LINE#         207
  C:0BF7H         LINE#         208
  -------         ENDPROC       _INHSAMPLEHANDLER
  -------         ENDMOD        INH

Deleted for brevity

  C:09FEH         PUBLIC        _Detect
  C:074EH         PUBLIC        main
  -------         PROC          _DETECT
  D:0026H         SYMBOL        iLed

  • Having mocked you of having less curiosity than me, I could hardly ignore your request. (I had to change your header files as I don't have those - I'm using an 8051F930 - so perhaps it's not an apples-apples comparison.)

    With optimization 4+ var1/var2 are at the same address. However the actual assembler code doesn't reference these and uses registers. Not a fair test.

    With optimization at 2, var1/var2 do not overlay each other. I would not expect this program to write anything other than 36 to P2.

    I have to change the code as follows to get the data to overlay:

    static void (*mHandler)(unsigned int uData);
    
    void sub1(unsigned char var1) {
            var1=0;                                                 //reset var1/var2
            if (var1) var1=0;                               //make sure var1 is always 0
            //P2=var1;                                              //make sure tmr0 is working
    }
    
    void sub2(unsigned char var2) {
            var2=var2+1;                                    //increment var1/var2
            if (var2==0) var2=1;                    //make sure var2 is never zero
            NOP256(); NOP256();                             //delay 512 ticks - create opportunity for tmr0 to fire at least once
            P2=var2;                                                //output var2 on P0
            if ( var2 == 0 )
            {
                    P2 = 1;
            }
    }
    
    void tmr0_isr(void) interrupt 1 {
    //              sub1(0);
            (*mHandler)(0);                                                //call sub1 periodically to reset var1/var2
    }
    
    int main(void) {
                    mHandler = sub1;
            TR0=0;                                                  //turn off tmr0
            TMOD = (TMOD & 0xf0) | 0x02;        //tmr0 in mode 2 (auto reload tl0 with th0
            TH0=-100;                                               //tmr strikes every 100 ticks
            TL0=TH0;
            ET0=1;                                                  //enable tmr0 interrupt
            TR0=1;                                                  //turn on tmr0
            EA=1;                                                   //enable global interrupt
    
            while (1) {
                    sub2(35);
            }
    }
    

    This code seems to suffer from the same problem as my program. In fact, from within Sub2 I got var2 == 0.

  • "This code seems to suffer from the same problem as my program. In fact, from within Sub2 I got var2 == 0."

    if you really had curiosity, you probably would have run it on different platforms and observed the differences in behavior and asked yourself why.

  • I actually claimed to have a lack of curiosity - and proud of it.

    Thanks to everyone here to for their contributions to a case solved. Especially to Ron who, strangely enough, found the solution but didn't recommend it.