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

arrays and ptrs: what are C_CSTOPTR and C_ISTOPTR for

Dear all,

I have problems with string in C51, and confused about the array and ptr processing in C51 while investigating the assembly code generated.

What is C_CSTOPTR and C_ISTOPTR for in the code?

Please note C_CSTOPTR is in char* access code, and C_ISTOPTR is in int[] code.

  71   1         unsigned char *cp = (unsigned char *)malloc(5);
  72   1         unsigned char ca[5];
  73   1         unsigned int  *ia = (unsigned int *)malloc(10);
  74   1         unsigned int  ip[5];
  75   1      
  76   1         for (i=0; i<5; i++) {
  77   2            ca[i] = i;
  78   2            cp[i] = i;
  79   2            ia[i] = i;
  80   2            ip[i] = i;
  81   2         }

Below is generated for the above code:

                                           ; SOURCE LINE # 77
0034 AF00    R     MOV     R7,i+01H
0036 7400    R     MOV     A,#LOW ca
0038 2500    R     ADD     A,i+01H
003A F582          MOV     DPL,A
003C E500    R     MOV     A,i
003E 3400    R     ADDC    A,#HIGH ca
0040 F583          MOV     DPH,A
0042 EF            MOV     A,R7
0043 F0            MOVX    @DPTR,A
                                           ; SOURCE LINE # 78
0044 900000  R     MOV     DPTR,#cp
0047 E0            MOVX    A,@DPTR
0048 FB            MOV     R3,A
0049 A3            INC     DPTR
004A E0            MOVX    A,@DPTR
004B FA            MOV     R2,A
004C A3            INC     DPTR
004D E0            MOVX    A,@DPTR
004E F9            MOV     R1,A
004F 850082  R     MOV     DPL,i+01H
0052 850083  R     MOV     DPH,i
0055 EF            MOV     A,R7
0056 120000  E     LCALL   ?C_CSTOPTR
                                           ; SOURCE LINE # 79
0059 E500    R     MOV     A,i+01H
005B 25E0          ADD     A,ACC
005D FF            MOV     R7,A
005E E500    R     MOV     A,i
0060 33            RLC     A
0061 FE            MOV     R6,A
0062 900000  R     MOV     DPTR,#ia
0065 E0            MOVX    A,@DPTR
0066 FB            MOV     R3,A
0067 A3            INC     DPTR
0068 E0            MOVX    A,@DPTR
0069 FA            MOV     R2,A
006A A3            INC     DPTR
006B E0            MOVX    A,@DPTR
006C F9            MOV     R1,A
006D 8F82          MOV     DPL,R7
006F 8E83          MOV     DPH,R6
0071 E500    R     MOV     A,i
0073 8500F0  R     MOV     B,i+01H
0076 120000  E     LCALL   ?C_ISTOPTR
                                           ; SOURCE LINE # 80
0079 E500    R     MOV     A,i+01H
007B 25E0          ADD     A,ACC
007D FF            MOV     R7,A
007E E500    R     MOV     A,i
0080 33            RLC     A
0081 FE            MOV     R6,A
0082 7400    R     MOV     A,#LOW ip
0084 2F            ADD     A,R7
0085 F582          MOV     DPL,A
0087 EE            MOV     A,R6
0088 3400    R     ADDC    A,#HIGH ip
008A F583          MOV     DPH,A
008C E500    R     MOV     A,i
008E F0            MOVX    @DPTR,A
008F A3            INC     DPTR
0090 E500    R     MOV     A,i+01H
0092 F0            MOVX    @DPTR,A

  • Please note C_CSTOPTR is in char* access code, and C_ISTOPTR is in int[] code.

    Hummmmm, I don't think it's correct because the C_CSTOPTR is in char* ( OK ), but the C_ISTOPTR is in int* code.

      71   1         unsigned char *cp = (unsigned char *)malloc(5);
      72   1         unsigned char ca[5];
      73   1         unsigned int  *ia = (unsigned int *)malloc(10);
      74   1         unsigned int  ip[5];
      75   1      
      76   1         for (i=0; i<5; i++) {
      77   2            ca[i] = i;
      78   2            cp[i] = i;
      79   2            ia[i] = i;
      80   2            ip[i] = i;
      81   2         }

    As far as I'm concerned you chose the variable name based in the method of data access, ca for an array and cp for a pointer ( c = char ).
    When you used the int data type, probably you mischanged the name. ia is your pointer and the access will use C_ISTOPTR.

    0044 900000  R     MOV     DPTR,#cp
    0047 E0            MOVX    A,@DPTR
    0048 FB            MOV     R3,A
    0049 A3            INC     DPTR
    004A E0            MOVX    A,@DPTR
    004B FA            MOV     R2,A
    004C A3            INC     DPTR
    004D E0            MOVX    A,@DPTR
    004E F9            MOV     R1,A
    004F 850082  R     MOV     DPL,i+01H
    0052 850083  R     MOV     DPH,i
    0055 EF            MOV     A,R7
    0056 120000  E     LCALL   ?C_CSTOPTR
                                               ; SOURCE LINE # 79
    0059 E500    R     MOV     A,i+01H
    005B 25E0          ADD     A,ACC
    005D FF            MOV     R7,A
    005E E500    R     MOV     A,i
    0060 33            RLC     A
    0061 FE            MOV     R6,A
    0062 900000  R     MOV     DPTR,#ia
    0065 E0            MOVX    A,@DPTR
    0066 FB            MOV     R3,A
    0067 A3            INC     DPTR
    0068 E0            MOVX    A,@DPTR
    0069 FA            MOV     R2,A
    006A A3            INC     DPTR
    006B E0            MOVX    A,@DPTR
    006C F9            MOV     R1,A
    006D 8F82          MOV     DPL,R7
    006F 8E83          MOV     DPH,R6
    0071 E500    R     MOV     A,i
    0073 8500F0  R     MOV     B,i+01H
    0076 120000  E     LCALL   ?C_ISTOPTR

  • whoops, I mixed the names. :)

    Anyway, what do C_CSTOPTR and C_ISTOPTR codes do for pointers?

  • Rather than worry about Keil's implementation details, what is your specific problem with strings in C51?

    Are your problems/confusion specific to C51, or is this a general 'C' language issue? (people often get confused over the similarities & differences of pointers & arrays in 'C').

    In the specific case of C51 pointers, note that a C51 pointer contains not only an address but must also define which memory space contains the addres; ie, CODE, DATA, IDATA, PDATA or XDATA.

    With an array, the memory space is known - and fixed - at compile time. Therefore the compiler doesn't have to allow for all the other memory spaces, and can generate more compact code.

    What happens to your code sample if you use memory-specific pointers instead of generic?

  • Andrew,

    First thanks for the reply.

    My compiled code is about 20K, and it contains some string processing code also. I'm experienced with C on Windows and Unix, but inexperienced in embedded world and C51.

    In general I have problems with strings in C51 (v3.20). I managed to make the code working but have some interesting observations:

    1__________________________________
    System has an LCD, and some text is displayed on it. When I remove an strncpy() usage in code, all the text
    to be written is corrupted and some garbage data is shown on LCD.

    Please note that the code which contains the removed strncpy() is not used when displaying other text on LCD.

    2________________________________
    In a function, I copy the string given with the parameter, to another string in a system struct. However, I could
    not copy the string with strncpy(). It simply copies an empty string.

    When I use memcpy instead of strcpy, everything is OK.

    3_______________________________
    Another problem is described here:
    http://www.keil.com/forum/msgpage.asp?MsgID=3529



    Please note that I use generic pointers. Because of these problems I could not solve, I try to understand the internal arch. of C51.

    An additional question: Is passing char[] to a function expecting char* creates a problem?

  • I'm afraid there's not enough detail there to draw any conclusions.
    Can you produce some small code snippets to illustrate the problems, and post them here?

    Is passing char[] to a function expecting char* creates a problem?

    In general 'C', they should be equivalent;
    In C51, I think you may well have to consider carefully the memory spaces involved?