Keil™, An ARM® Company

Technical Support

C51: ARRAY INDEX USES BYTE INSTEAD OF WORD


Information in this article applies to:

  • Cx51 All Versions

QUESTION

I have defined a union for byte-wise access of array elements. However, the compiler ignores the high byte of the index value. For example:

union  {
  long la[100];
  char ca[100];
} xdata u;

char getca (unsigned int i)  {
  return u.ca[i];
}

The compiler does not use the high byte of 'i' (passed in R6) to access the union. What is wrong?

char getca (unsigned int i)  {
;---- Variable 'i' assigned to Register 'R6/R7' ----
  return u.ca[i];
0000 7400        R     MOV     A,#LOW u
0002 2F                ADD     A,R7
0003 F582              MOV     DPL,A
0005 7400        R     MOV     A,#HIGH u
0007 3E                CLR     A         ; HIGH BYTE IGNORED!
0008 F583              MOV     DPH,A
000A E0                MOVX    A,@DPTR
000B FF                MOV     R7,A
}
000C 22                RET

ANSWER

You have defined the 'ca' element of the union as just 100 bytes. Since the element size is less than 256 bytes, the compiler does not need the high byte of the index value for correct access.

There are two ways to solve your problem:

  1. Define the proper array size. For example:
    union  {
      long la[100];
      char ca[100*sizeof(long)];
    } xdata u;
    
  2. If your union definition is more complex than in the simplified example you may use an explicit pointer cast. This prevents the compiler from using the array size to optimize pointer accesses-all offset calculations are performed using all 16-bits. For example:
    return ((char *)u.ca)[i];
    

Last Reviewed: Saturday, April 24, 2004


Did this article provide the answer you needed?
 
Yes
No
Not Sure