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
  • Thanks for you're response,

    I've tested it but the only difference i see is the value changes to 0x43 with 4 or less characters.

  • Hmmmm,

    I just tried your program using V8.05a and everything works exactly as I expected. I do not see the problems you have. I tested the string "1", "12", "123", "1234", and "12345" and P1 was set to 0x01, 0x02, 0x03, 0x04, and 0x05 respectively.

    I then looked at the generated code to see if there was a problem. And, it does exactly what it is supposed to.

    Maybe there is some kind of problem with your target hardware. I would start looking at port 1.

    Jon

  • The hardware i'm using is a development board with the TUSB3210 controller on it. The board itself is some kind of starter kit and comes from a retailer.

    I don't think there's something wrong with the hardware because i did not had any problems with the SDCC compiler. I've also tried the UVision simulator and everything worked fine.

    But running it on the hardware there's some kind of problem with the null terminating character.

  • Did you look at the generated code to see if it looked OK?

    I mean if it runs OK on the simulator but it fails on the hardware and there was no difference in the software, then there is some difference between the hardware and the simulation environment.

    My guess is that you are using some area of memory for your program that is also used by the hardware for some purpose.

    Jon

  • Here's another idea. Since your function is basically strlen, why don't you do the following:

    P1 = strlen ("123");
    

    and see if that fails. If it does, then we KNOW that there is some kind of hardware issue and not a compiler problem.

    Jon

  • 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