Hi all,
I've this strange problem with the \0 character. I'll show you the code first:
#include <REG52.H> void test(char *s) { int idx; for(idx = 0; *s != '\0'; idx++, s++) { } P1 = idx; // Led's are connected to P1 so i can see the idx value. } void main() { test("12345"); while(1); }
Now the problem: When i call the test function with 4 characters or less, the condition
*s != '\0'
does not work. The led's show me a value of 0x63 when i call the test function with 1, 2, 3 or 4 characters. There's no problem when i call the test function with 5 characters or more. The led's show me 0x05 with a call of 5 characters.
I've also tested this code with the SDCC compiler and the call with 4 characters or less did worked like it should.
I'm working with the C51 COMPILER V8.05a
Any ideas? Thanks!
Following is the generated code for a test string of 3 characters:
C51 COMPILER V8.05a, COMPILATION OF MODULE MAIN OBJECT MODULE PLACED IN main.OBJ COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE main.c DEBUG OBJECTEXTEND CODE SYMBOLS 1 #include 2 3 void test(char *s) 4 { 5 1 int idx; 6 1 7 1 for(idx = 0; *s != '\0'; idx++, s++) 8 1 { 9 2 } 10 1 11 1 P1 = idx; // Led's are connected to P1 so i can see the idx value. 12 1 } 13 14 void main() 15 { 16 1 test("123"); 17 1 18 1 while(1); 19 1 } ASSEMBLY LISTING OF GENERATED OBJECT CODE ; FUNCTION _test (BEGIN) ; SOURCE LINE # 3 ;---- Variable 's' assigned to Register 'R1/R2/R3' ---- ; SOURCE LINE # 4 ; SOURCE LINE # 7 ;---- Variable 'idx' assigned to Register 'R6/R7' ---- 0000 E4 CLR A 0001 FF MOV R7,A 0002 FE MOV R6,A 0003 ?C0001: 0003 120000 E LCALL ?C?CLDPTR 0006 600E JZ ?C0002 ; SOURCE LINE # 8 ; SOURCE LINE # 9 0008 0F INC R7 0009 BF0001 CJNE R7,#00H,?C0008 000C 0E INC R6 000D ?C0008: 000D 7401 MOV A,#01H 000F 29 ADD A,R1 0010 F9 MOV R1,A 0011 E4 CLR A 0012 3A ADDC A,R2 0013 FA MOV R2,A 0014 80ED SJMP ?C0001 0016 ?C0002: ; SOURCE LINE # 11 0016 8F90 MOV P1,R7 ; SOURCE LINE # 12 0018 22 RET ; FUNCTION _test (END) ; FUNCTION main (BEGIN) ; SOURCE LINE # 14 ; SOURCE LINE # 15 ; SOURCE LINE # 16 0000 7BFF MOV R3,#0FFH 0002 7A00 R MOV R2,#HIGH ?SC_0 0004 7900 R MOV R1,#LOW ?SC_0 0006 120000 R LCALL _test 0009 ?C0005: ; SOURCE LINE # 18 0009 80FE SJMP ?C0005 ; FUNCTION main (END)
And following is the code for a test string of 5 characters:
C51 COMPILER V8.05a, COMPILATION OF MODULE MAIN OBJECT MODULE PLACED IN main.OBJ COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE main.c DEBUG OBJECTEXTEND CODE SYMBOLS line level source 1 #include 2 3 void test(char *s) 4 { 5 1 int idx; 6 1 7 1 for(idx = 0; *s != '\0'; idx++, s++) 8 1 { 9 2 } 10 1 11 1 P1 = idx; // Led's are connected to P1 so i can see the idx value. 12 1 } 13 14 void main() 15 { 16 1 test("12345"); 17 1 18 1 while(1); 19 1 } ASSEMBLY LISTING OF GENERATED OBJECT CODE ; FUNCTION _test (BEGIN) ; SOURCE LINE # 3 ;---- Variable 's' assigned to Register 'R1/R2/R3' ---- ; SOURCE LINE # 4 ; SOURCE LINE # 7 ;---- Variable 'idx' assigned to Register 'R6/R7' ---- 0000 E4 CLR A 0001 FF MOV R7,A 0002 FE MOV R6,A 0003 ?C0001: 0003 120000 E LCALL ?C?CLDPTR 0006 600E JZ ?C0002 ; SOURCE LINE # 8 ; SOURCE LINE # 9 0008 0F INC R7 0009 BF0001 CJNE R7,#00H,?C0008 000C 0E INC R6 000D ?C0008: 000D 7401 MOV A,#01H 000F 29 ADD A,R1 0010 F9 MOV R1,A 0011 E4 CLR A 0012 3A ADDC A,R2 0013 FA MOV R2,A 0014 80ED SJMP ?C0001 0016 ?C0002: ; SOURCE LINE # 11 0016 8F90 MOV P1,R7 ; SOURCE LINE # 12 0018 22 RET ; FUNCTION _test (END) ; FUNCTION main (BEGIN) ; SOURCE LINE # 14 ; SOURCE LINE # 15 ; SOURCE LINE # 16 0000 7BFF MOV R3,#0FFH 0002 7A00 R MOV R2,#HIGH ?SC_0 0004 7900 R MOV R1,#LOW ?SC_0 0006 120000 R LCALL _test 0009 ?C0005: ; SOURCE LINE # 18 0009 80FE SJMP ?C0005 ; FUNCTION main (END)
Careful comparison between the test function will show that they are identical.
So, if it works with 5 characters or more but fails for 4 characters or less, the problem would not appear to come from the generated code.
Jon