We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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] ;
Sorry for the long delay in responding. I forgot to check back right away and a month slipped by. My test was a little different in that I used local parameters. Note the code expansion for line #96 versus #97. This test was compiled with v3.20b. I used the following compiler options: CD SB DB XSMALL OT(3,SPEED) DF(PROCESSOR=251) ---------------------------------- 89 void main(void) 90 { 91 1 char tt[30]; 92 1 char test ; 93 1 unsigned char aaa = 27 ; 94 1 unsigned int bbb = 27 ; 95 1 96 1 test = tt[aaa - 20] ; 97 1 test = tt[bbb - 20] ; 98 1 } ------------------------------------ ; FUNCTION main (BEGIN) ; SOURCE LINE # 89 ; SOURCE LINE # 90 ; SOURCE LINE # 93 000000 7E701B MOV R7,#01BH ;---- Variable 'aaa' assigned to Register 'R7' ---- ; SOURCE LINE # 94 000003 7E24001B MOV WR4,#01BH ;---- Variable 'bbb' assigned to Register 'WR4' ---- ; SOURCE LINE # 96 000007 0A37 MOVZ WR6,R7 000009 09730000 R MOV R7,@WR6+tt-20 ;---- Variable 'test' assigned to Register 'R7' ---- ; SOURCE LINE # 97 00000D 09720000 R MOV R7,@WR4+tt+65516 ; SOURCE LINE # 98 000011 22 RET ; FUNCTION main (END) -------------------------------- Joel
Joel, -20 and 65516 translate into the same 16-bit hex value 0xFFEC. So the offset is in both cases identical. I agree that the listing might be a little clearer, but the code seems correct to me.
-20 and 65516 do not translate into the same 24-bit hex value! This is the 251 with 24-bit addressing. I got entirely different behavior in my indexed addressing between the two forms because they weren't looking at the same memory space (e.g. 00 space versus 01 space). Joel
-20 and 65516 do not translate into the same 24-bit hex value! You are right. But that is not important. The move is using a WORD register (16-bits) and not a DOUBLE register. If you look at the 2 instructions:
MOV R7,@WR6+tt-20 MOV R7,@WR4+tt+65516
MOV Rm, @WRj + dis16
0xFF0022 0973FFEC MOV R7,@WR6+0xFFEC 0xFF0026 0972FFEC MOV R7,@WR4+0xFFEC
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
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); }
; 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