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

No MULTIPLE CALL TO SEGMENT warning where it should be...

Please consider the following code.

//--- module main.c ---

...

void main() {
        ...
        set_status_word(...);
        ...
}

//--- module can.c ---

...

void CAN_int_handler(void) interrupt 7 {
        ...
        set_status_word(...);
        ...
}

//--- module utils.c ---

...

void set_status_word(...) {
        ...
}

If you replace the calls to set_status_word() with calls to printf(), the linker issues a "multiple call to segment" warning, but, like this, this code causes no warnings. Why not? I looked at the assembler output of the set_status_word() function and noticed that it isn't using absolute register addressing. Can this relate somehow?

Parents Reply Children
  • Christoph,

    Thanks for your response. Yes, set_status_word() just modifies status_word:

    unsigned char xdata status_word;
    
    void set_status_word(unsigned char err, bit yes) {
            if (yes)
                    status_word &= err;
            else
                    status_word |= (~err & 0xF);
    }
    

    The memory model is large, so the parameters are passed via XDATA:

    0014 900000      R     MOV     DPTR,#err
    0017 E0                MOVX    A,@DPTR
    0018 FF                MOV     R7,A
    ...
    

    Obviously, this can lead to unpredictable behaviour, can't it? *sigh* Ok, I wrote this too fast. This function can still result in a garbled value of status_word, because each of the two bytes is written individually. If there's an interrupt (with another call of set_status_word()) right after the first byte is written, status_word might get set to an erroneous value. All right, but what are the exact criteria the linker uses for deciding whether to issue or not to issue that message?

  • Obviously, this can lead to unpredictable behaviour, can't it?

    ... ohh yes. ;)

    All right, but what are the exact criteria the linker uses for deciding whether to issue or not to issue that message?

    Maybe the linker assumes that function arguments are passed in registers when they really aren't ?

    This could be a bug in the linker. Did you file a bug report ?