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

eorror of multiple call to segment

Hi,

The compile error is:

WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_STRTONUM?PARSE
CALLER1: ?PR?TC0?PERIPHERAL
CALLER2: ?C_C51STARTUP

The callers TC0 is an ISR using reg bank 2 and I don't know about the c51startup. The called function STRTONUM is using the directive of #pragma NOAREGS so can be called for any functions. The question is why I still got the multiple call error? Thanks for answering my question.

By the way, C51 is V6.21, BL51 is V4.21 and LIB51 is V4.20.

chao.

Parents
  • #pragma disable seems to generate code thus:

    ; prologue
           SETB    C
           JBC     EA,?C0069
           CLR     C
    ?C0069:
           PUSH    PSW
    
    ; epilogue
           POP     PSW
           MOV     EA,C
           RET
    

    That is, it's remembering the state of EA in the carry bit, and storing the carry bit (as part of PSW) on the stack. In my 8051 assembler naivete, I wrote code for the same purpose thus:

    ; prologue
           PUSH    IE
           CLR     EA
    
    ; epilogue
           POP     IE
           RET
    

    which seems more straightforward. So what's going to go wrong with this method? Why do we need to get the carry bit involved? Or is it just that the compiler "owns" the carry bit, and that way it doesn't have to worry about the C routine changing other bits in IE?

Reply
  • #pragma disable seems to generate code thus:

    ; prologue
           SETB    C
           JBC     EA,?C0069
           CLR     C
    ?C0069:
           PUSH    PSW
    
    ; epilogue
           POP     PSW
           MOV     EA,C
           RET
    

    That is, it's remembering the state of EA in the carry bit, and storing the carry bit (as part of PSW) on the stack. In my 8051 assembler naivete, I wrote code for the same purpose thus:

    ; prologue
           PUSH    IE
           CLR     EA
    
    ; epilogue
           POP     IE
           RET
    

    which seems more straightforward. So what's going to go wrong with this method? Why do we need to get the carry bit involved? Or is it just that the compiler "owns" the carry bit, and that way it doesn't have to worry about the C routine changing other bits in IE?

Children
  • So what's going to go wrong with this method?


    This works!

    #pragma disable
    void init_serial_isr (void)
    {
    ES = 1;  /* enable serial interrupts */
    }


    This does not!

    ; prologue
           PUSH    IE
           CLR     EA
    
           SETB    ES
    
    ; epilogue
           POP     IE
           RET

    Jon

  • That's the sort of thing I had in mind in the last sentence (the C routine making other changes to IE). The compiler has to play it safe for the general case.

    In my case, I have the advantage of some extra information about what the routines are doing, so preserving IE modification isn't a problem.

    I suddenly panicked that I had overlooked some subtle 8051-ism about disabling interrupts and just hadn't noticed the error in the lab yet.