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

Another Optimization Problem

Greetings all,

I'm fairly new to the Keil Toolset and had a question regarding the C51 code optimization levels.

It seems that on Level 8: Reuse Common Entry Code (default), the main() entry function gets completely optimized out if the main() function grows too large. I can avoid this by either changing the optimization level, or by adding the debug flag in the Output tab.

The actual assembly is correct in the .LST file, but if I check the hex file, the main() function doesn't appear at the location specified by the map file.

Is this normal behaviour? Is there some setting I'm misinterpreting somewhere?


TIA,
JG.

Parents
  • I compiled your example. Here are my results.

    1. I ALWAYS receive the following linker warning:

    *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?DUMMYCALL?MAIN

    This makes sense because the main function never actually calls DummyCall and the optimizer figures this out.

    2. For compiling with and without debug information, I use the Debug Information checkbox in the Project Options - Output tab.

    3. Compiling with debug information ON yields the following in the debugger.

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     main(C:000F)
         7: void main()
         8: {
         9: unsigned char Temp_A;
        10: unsigned char Temp_B;
        11:
        12:         Temp_A = 0;
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
        13:         Temp_B = 1;
        14:
    C:0x0011    7E01     MOV      R6,#0x01
        15:         COM0 = 0x55;
        16:
    C:0x0013    75BC55   MOV      COM0(0xBC),#0x55
        17:         while(1);
    C:0x0016    80FE     SJMP     C:0016
         3: void DummyCall()
    C:0x0018    22       RET

    4. Compiling with debug information OFF yields the following:

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     C:000F
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
    C:0x0011    7E01     MOV      R6,#0x01
    C:0x0013    75BC55   MOV      0xBC,#0x55
    C:0x0016    80FE     SJMP     C:0016
    C:0x0018    22       RET      

    These appear to be identical to me.

    5. Finally, I created a HEX file from the build with debug information and I created a HEX file from the build with no debug information. They were identical.

    So, here are a few suggestions.

    • Make sure that we're build the project the same way.

    • Test the HEX files generated from the debug version and the non-debug version to see if they are the same.

    • How are you debugging? Are you using the Keil debugger or another debugger? If using another debugger, how old (or new) is it? Has it incorporated all the latest changes to the OMF51 specification?

    Jon

Reply
  • I compiled your example. Here are my results.

    1. I ALWAYS receive the following linker warning:

    *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?DUMMYCALL?MAIN

    This makes sense because the main function never actually calls DummyCall and the optimizer figures this out.

    2. For compiling with and without debug information, I use the Debug Information checkbox in the Project Options - Output tab.

    3. Compiling with debug information ON yields the following in the debugger.

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     main(C:000F)
         7: void main()
         8: {
         9: unsigned char Temp_A;
        10: unsigned char Temp_B;
        11:
        12:         Temp_A = 0;
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
        13:         Temp_B = 1;
        14:
    C:0x0011    7E01     MOV      R6,#0x01
        15:         COM0 = 0x55;
        16:
    C:0x0013    75BC55   MOV      COM0(0xBC),#0x55
        17:         while(1);
    C:0x0016    80FE     SJMP     C:0016
         3: void DummyCall()
    C:0x0018    22       RET

    4. Compiling with debug information OFF yields the following:

    C:0x0000    020003   LJMP     C:0003
    C:0x0003    787F     MOV      R0,#0x7F
    C:0x0005    E4       CLR      A
    C:0x0006    F6       MOV      @R0,A
    C:0x0007    D8FD     DJNZ     R0,C:0006
    C:0x0009    758107   MOV      SP(0x81),#0x07
    C:0x000C    02000F   LJMP     C:000F
    C:0x000F    E4       CLR      A
    C:0x0010    FF       MOV      R7,A
    C:0x0011    7E01     MOV      R6,#0x01
    C:0x0013    75BC55   MOV      0xBC,#0x55
    C:0x0016    80FE     SJMP     C:0016
    C:0x0018    22       RET      

    These appear to be identical to me.

    5. Finally, I created a HEX file from the build with debug information and I created a HEX file from the build with no debug information. They were identical.

    So, here are a few suggestions.

    • Make sure that we're build the project the same way.

    • Test the HEX files generated from the debug version and the non-debug version to see if they are the same.

    • How are you debugging? Are you using the Keil debugger or another debugger? If using another debugger, how old (or new) is it? Has it incorporated all the latest changes to the OMF51 specification?

    Jon

Children