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

Array indexing with unsigned int

C251 v3.12

The C251 compiler does not handle arithmetic for array indices consistently. Consider

char tt[30] ;
char test ;
unsigned char aaa = 27 ;
unsigned int  bbb = 27 ;

test = tt[aaa - 20] ;
test = tt[bbb - 20] ;
The assembly code for the index using the unsigned char (aaa) has "-20" in its address construction. The assembly code for the index using the unsigned int (bbb) has "+65576" in its address construction. OOPS!
With the 8051's 16-bit address, this is no problem, but when using far addressing on the 251 you end up in different memory banks. int and char index variables work correctly like the unsigned char.

Parents
  • Thanks for discussion. I'll take another look at what happened in the first place.

    By the way, I've been checking if other old bugs were fixed in C251 v3.20b.
    1. The need to explicitly use using 0 in main() is gone.
    2. An old bug in v2 I posted over a year ago (before you remodeled your discussion forum) about using sbit and _at_ together is fixed. Since I had a work-around, I never checked back on it until now.

    Thanks. Joel

Reply
  • Thanks for discussion. I'll take another look at what happened in the first place.

    By the way, I've been checking if other old bugs were fixed in C251 v3.20b.
    1. The need to explicitly use using 0 in main() is gone.
    2. An old bug in v2 I posted over a year ago (before you remodeled your discussion forum) about using sbit and _at_ together is fixed. Since I had a work-around, I never checked back on it until now.

    Thanks. Joel

Children
  • 1. The need to explicitly use using 0 in main() is gone.

    I've never heard of this problem. Register bank 0 is selected by default. Why did you need to specify it in your application?

    Jon

  • I finally had some time to look at the array indexing problem. There are a lot details that may or not be relevant. My program ROM and hardware memory map reside in 0xFF space. My system RAM is in 0x00 space.

    typedef unsigned char BYTE ;
    typedef unsigned int  WORD ;
    typedef struct {
      BYTE dac;
      BYTE x1;
      BYTE roll;
      BYTE x2;
    } ASIC_AGS ;
    enum {
      DCA_LEL_WRDAC=1,
      DCA_LEH_WRDAC,
      DET_BIAS_WRDAC,
      AGS_DAC_1_WRDAC=24,
      AGS_ECHO_WRDAC=40,
      LASER_WRDAC,
      END_LIST_WRDAC
    } ;
    
    export volatile ASIC_AGS far asic_ags[16] _at_ 0xFFFFA0 ;
    
    void local_func(WORD dacID, WORD dacVal)
    {
      BYTE ch ;
      BYTE far * tempointer1 ;
      BYTE far * tempointer2 ;
    
      if((dacID<AGS_DAC_1_WRDAC)||(dacID>AGS_ECHO_WRDAC))
      { /* Do something else */ }
    
      /* case 1 */
      asic_ags[dacID - AGS_DAC_1_WRDAC] = (BYTE)dacVal ;
      tempointer1 = (BYTE far *)(&asic_ags[dacID - AGS_DAC_1_WRDAC].dac) ;
    
      /* case 2 */
      ch = dacID - AGS_DAC_1_WRDAC ;
      asic_ags[ch] = (BYTE)dacVal ;
      tempointer2 = (BYTE far *)(&asic_ags[ch].dac) ;
    
      /* print to system debug port */
      sprintf(msg,"t1 = %lX, t2 = %lX", tempointer1, tempointer2);
      debug_msg(msg);
    }
    
    My printout is:
    t1 = 100FFA0, t2 = FFFFA0
    And in both cases, the value ends up where address points: case 2 goes to my DAC, but case 1 ends up in system RAM (0xFFA0)!

    Assembly listing:
    ; case 1
      mov  wr6,wr14
      sll  wr6
      sll  wr6
      mov  wr14,#WORD0 asic_ags+65440
      mov  wr12 #WORD2 asic_ags+65440
      add  wr14,wr6
    ;--- 'tempointer1' assigned to Reg DR12 ---
    
    ; case 2
      mov  r10,ch
      mov  a,#4
      mul  ab
      mov  wr2,#WORD0 asic_ags
      mov  wr0,#WORD2 asic_ags
      add  wr2,wr10
      mov  tempointer2,dr0
    


    -------------------------------
    Regarding the using 0 problem. When I first installed v3.12, I started getting bizarre behavior when making simple changes to my code. I looked in the linker (v3.14) file and found variables assigned to locations 0 to 7 (bank 0). Rearranging variable defintions made the linker put different variables in bank 0 and the bizarre behavior would change. Only by explicitly adding using 0 to the main definition did the linker stop assigning variables to bank 0.

    I just went back and tried v3.12 again and commented out the using 0 from the main definition and the linker did its old trick of assigning variables to bank 0. The linker in v3.20 doesn't do this.

    Joel