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

Null terminating character

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!

Parents Reply Children
  • As it appears to have a compiler dependance, I'm suspicious that it might be an optimisation problem. Have you tried turning optimisation off?

  • I guess you didn't see my post that I tried M. Swiebertje's code (as posted) with the same compiler and it runs fine here. Also, M. Swiebertje reports that it runs fine in the Keil simulator. I really doubt that the simulator simulates it correctly but the hardware does not.

    However, without knowing the following...

    • Memory map of the target hardware.
    • Compiler/Linker settings used to build the application with the Keil tools.
    • Compiler/Linker settings used to build the application with SDCC.
    • Configuration of the test environment.

    ...it's impossible to accurately GUESS what's going on.

    However, based on all the evidence provided, it does not appear to be a problem with the compiler.

    Since it is possible to see the code generated by the Keil compiler, I would think that a true engineer would at least glance at that to see if it looks OK or not (maybe I'm wrong). Also, based on the trivality of the code, I would also assume that commentators would at least try to run it and see what the results were before making wild speculation. It took me less than 5 minutes to compile and test the example provided.

    Jon

  • 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