ARM Technical Support Knowledge Articles

ARRAY INDEX USES BYTE INSTEAD OF WORD

Applies to: C51 C Compiler

Answer


Information in this article applies to:


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];
    

Article last edited on: 2004-04-24 12:14:49

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential