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

C51 Regarding generic pointers and the use of 2 DPTRs

I am writing code that requires a fair amount of pointer arithmetic and manipulation. The C51 compiler appears to generate lots of generic pointers (much too my dismay). Is there any way to use the built in dual DPTR's to reduce the massive overhead associated with generic pointers significantly? The C51 derivative I'm using (MCS12XX) does have dual data pointers as far as I can tell.

I've attempted judicious use of the

#pragma modp2


directive with no visible change in the code output from the compiler.
Specifically I am generating graphic information that is sent to a memory mapped graphic LCD. It works just fine that's not the problem. The problem is code space and the overhead that the generic pointers have are going to make things difficult to complete as wished. So is there a way to get around this?

Stephen

Parents
  • void func (u8 *pointer)
    will use generic pointers

    a function like
    void func (u8 xdata *pointer)
    will use a non-generic XDATA pointer

    if you tell your functions where the data is they need not do the generic stuff

    I actually often make two copies of a routine like

    void RalphX(u8 xdata * data pointer)
    and
    void RalphC(u8 code * data pointer)

    just to avoid the overhead

    here is the skinny

    char helloX  (unsigned char xdata  *ptr)
    {
      return  *ptr;
    
    }
    
    char hello  (unsigned char  *ptr)
    {
      return  *ptr;
    
    }
    
    
    gives
    
                 ; FUNCTION _helloX (BEGIN)
                                               ; SOURCE LINE # 646
    0000 8E00        R     MOV     ptr,R6
    0002 8F00        R     MOV     ptr+01H,R7
                                               ; SOURCE LINE # 647
                                               ; SOURCE LINE # 648
    0004 AE00        R     MOV     R6,ptr
    0006 AF00        R     MOV     R7,ptr+01H
    0008 8F82              MOV     DPL,R7
    000A 8E83              MOV     DPH,R6
    000C E0                MOVX    A,@DPTR
    000D FF                MOV     R7,A
                                               ; SOURCE LINE # 650
    000E         ?C0127:
    000E 22                RET
    C51 COMPILER V7.10   SPUSB                                                                 08/03/2007 13:20:28 PAGE 65
    
                 ; FUNCTION _helloX (END)
    
                 ; FUNCTION _hello (BEGIN)
                                               ; SOURCE LINE # 652
    0000 8B00        R     MOV     ptr,R3
    0002 8A00        R     MOV     ptr+01H,R2
    0004 8900        R     MOV     ptr+02H,R1
                                               ; SOURCE LINE # 653
                                               ; SOURCE LINE # 654
    0006 AB00        R     MOV     R3,ptr
    0008 AA00        R     MOV     R2,ptr+01H
    000A A900        R     MOV     R1,ptr+02H
    000C 120000      E     LCALL   ?C?CLDPTR
    000F FF                MOV     R7,A
                                               ; SOURCE LINE # 656
    0010         ?C0128:
    0010 22                RET
                 ; FUNCTION _hello (END)
    

    Erik

Reply
  • void func (u8 *pointer)
    will use generic pointers

    a function like
    void func (u8 xdata *pointer)
    will use a non-generic XDATA pointer

    if you tell your functions where the data is they need not do the generic stuff

    I actually often make two copies of a routine like

    void RalphX(u8 xdata * data pointer)
    and
    void RalphC(u8 code * data pointer)

    just to avoid the overhead

    here is the skinny

    char helloX  (unsigned char xdata  *ptr)
    {
      return  *ptr;
    
    }
    
    char hello  (unsigned char  *ptr)
    {
      return  *ptr;
    
    }
    
    
    gives
    
                 ; FUNCTION _helloX (BEGIN)
                                               ; SOURCE LINE # 646
    0000 8E00        R     MOV     ptr,R6
    0002 8F00        R     MOV     ptr+01H,R7
                                               ; SOURCE LINE # 647
                                               ; SOURCE LINE # 648
    0004 AE00        R     MOV     R6,ptr
    0006 AF00        R     MOV     R7,ptr+01H
    0008 8F82              MOV     DPL,R7
    000A 8E83              MOV     DPH,R6
    000C E0                MOVX    A,@DPTR
    000D FF                MOV     R7,A
                                               ; SOURCE LINE # 650
    000E         ?C0127:
    000E 22                RET
    C51 COMPILER V7.10   SPUSB                                                                 08/03/2007 13:20:28 PAGE 65
    
                 ; FUNCTION _helloX (END)
    
                 ; FUNCTION _hello (BEGIN)
                                               ; SOURCE LINE # 652
    0000 8B00        R     MOV     ptr,R3
    0002 8A00        R     MOV     ptr+01H,R2
    0004 8900        R     MOV     ptr+02H,R1
                                               ; SOURCE LINE # 653
                                               ; SOURCE LINE # 654
    0006 AB00        R     MOV     R3,ptr
    0008 AA00        R     MOV     R2,ptr+01H
    000A A900        R     MOV     R1,ptr+02H
    000C 120000      E     LCALL   ?C?CLDPTR
    000F FF                MOV     R7,A
                                               ; SOURCE LINE # 656
    0010         ?C0128:
    0010 22                RET
                 ; FUNCTION _hello (END)
    

    Erik

Children
  • I, usually, do not take the time to do so, but I got curious to see how valid a 'rule' I put on myself years ago (NEVER a generic pointer) actually was.

    I found it even more valid than I remembered.

    Erik

    PS the above refer to Keil C51 nothing else, it may and may not be valid for others.

  • I should have mentioned that LCALL ?C?CLDPTR is the real 'overhead generator' in the example I gave.

    Erik

  • First thanks for explaining what was going on with the generic pointers. I guess I didn't tweak on the compiler enough to find out the internal pointer abuse going on. I plan to abuse xdata pointers more.

    Indeed Erik that is what I discovered (amongst other surprises). So if I use an explicit pointer in this case it will reduce overhead. The generic pointers have been a killer (sigh) so I plan on doing something like

    #define LPTR xdata
    

    and putting that in front of anything that's suffering from generic data pointers horribly. That way if the code goes to a different processor I just redefine that to an empty define and it becomes normal.

    Stephen