Keil Logo

What's New in C51 Version 9.61

C51 Version 9.61 Release

Release Date: 19th December, 2022

  • [Consideration prior to installation]
    • By default, the installation destination folder is specified as 'C:/Keil_v5/'. In this filesystem location all local users have full access permissions. For enhanced security, users may choose to install the product into their %LOCALAPPDATA% folder (C:/Users/<user>/AppData/Local/Keil_v5/) where access is restricted to the current local user and users with administration permissions. Note that 'Show hidden files' needs to be enabled for browsing to the %LOCALAPPDATA% folder.
  • [CX51 Compiler]
    • Corrected: the reentrant attribute was silently ignored in typedef declarations. Example:
      C code example
      
      typedef void (footype) (void) reentrant;
      footype foo;
      
      void foo(void) reentrant;
      
    • Removed: superfluous code generation in case of comparing char with small int values. Example:
      C code example
      
      char x, y;
      
      for (x = 0; x < 13; x++)
          y++;
      
      Old generated code:
      ;---- Variable 'x' assigned to Register 'R7' ----
      0010 E4                CLR     A
      0011 FF                MOV     R7,A
      0012         ?C0003:
      0012 EF                MOV     A, R7
      0013 C3                CLR     C
      0014 940D              SUBB    A, #0DH
      0016 7E80              MOV     A, #80H
      0018 9480              SUBB    A, #80H
      001A 5005              JNC     ?C0004
                                                 ; SOURCE LINE # 46
      001C 0500        R     INC     y
                                                 ; SOURCE LINE # 47
      001E 0F                INC     R7
      001F 80F1              SJMP    ?C0003
      0021         ?C0004:
      
      New generated code:
      ;---- Variable 'x' assigned to Register 'R7' ----
      0010 E4                CLR     A
      0011 FF                MOV     R7,A
      0012         ?C0003:
                                                 ; SOURCE LINE # 46
      0012 0500        R     INC     y
                                                 ; SOURCE LINE # 47
      0014 0F                INC     R7
      0015 BF0DFA            CJNE    R7,#0DH,?C0003
      0018 80F3              SJMP    ?C0001
      
    • Corrected: if there is an error in a function parameter it can happen that the compiler terminates unexpectedly without printing out an error summary. Example:
      C code example
      
      int message() {
        if (strncmp(rx_array[0], (char *)',', 1) == 0)
          rx_array[1] = 0;
      }
      
    • Corrected: if an unsigned char is compared with a small int constant the unsigned char is promoted to int. This is correct according to the C standard but leads to bigger code. This optimization was removed because of another bug fix in version 9.59. The optimization now is done again. Example:
      C code example
      
      void fkt(unsigned char x) {
        if (x >= 10) {
          dummy = 0;
        }
      }
      
    • Corrected: a erroneous code generation when the option NOINTPROMOTE is used to compare a long constant with a small constant. Example:
      C code example
      
      static volatile unsigned long longVar = 0x10000;
      static          unsigned char flag    = 0;
      
      void main (void)  {
        if (longVar <= 1024u) {    // the type of the constant (unsigned int) is used for comparison, not long
          Flag = 1;
        }  while (1);
      }
      
      Generated wrong code:
                   ; FUNCTION main (BEGIN)
                                                 ; SOURCE LINE # 5
                                                 ; SOURCE LINE # 7
      0000 AE00        R     MOV     R6,longVar+02H
      0002 AF00        R     MOV     R7,longVar+03H
      0004 D3                SETB    C
      0005 EF                MOV     A,R7
      0006 9400              SUBB    A,#00H
      0008 EE                MOV     A,R6
      0009 9404              SUBB    A,#04H
      000B 5003              JNC     ?C0002
                                                 ; SOURCE LINE # 8
      000D 750001      R     MOV     flag,#01H
                                                 ; SOURCE LINE # 9
      0010         ?C0002:
                                                 ; SOURCE LINE # 11
      0010 80FE              SJMP    ?C0002
                   ; FUNCTION main (END)
      
      Generated correct code:
                   ; FUNCTION main (BEGIN)
                                                 ; SOURCE LINE # 5
                                                 ; SOURCE LINE # 7
      0000 E4                CLR     A
      0001 FF                MOV     R7,A
      0002 7E04              MOV     R6,#04H
      0004 FD                MOV     R5,A
      0005 FC                MOV     R4,A
      0006 AB00        R     MOV     R3,longVar+03H
      0008 AA00        R     MOV     R2,longVar+02H
      000A A900        R     MOV     R1,longVar+01H
      000C A800        R     MOV     R0,longVar
      000E D3                SETB    C
      000F 120000      E     LCALL   ?C?SLCMP
                                                 ; SOURCE LINE # 8
      0012 5003              JNC     ?C0002
      0014 750005      R     MOV     flag,#01H
                                                 ; SOURCE LINE # 9
      0017         ?C0002:
                                                 ; SOURCE LINE # 11
      0017 80FE              SJMP    ?C0002
                   ; FUNCTION main (END)
      
    • Corrected: in rare cases wrong code could be generated for interrupt functions used in CPUs with 2 or more activated DTPRs. The configured compiler code optimization as well as the linker code packing settings did not influence this behavior.
    • Corrected: an erroneous code generation with missing integer promotion if explicit casts are used. Example:
      C code example
      
      volatile unsigned char aa,bb,cc,dd;
      
      void main (void)  {
        aa = 0xab;
        bb = 0xcd;
        cc = (aa+bb)%255;                   // cc=0x79   <-- correct
        dd = (unsigned char)((aa+bb)%255);  // dd=0x78   <-- wrong
        cc = (aa+bb)/255;                   // cc=0x01   <-- correct
        dd = (unsigned char)((aa+bb)/255);  // dd=0x00   <-- wrong
        while(1);
      }
      
    • Corrected: under some circumstances the compiler mistakenly optimize out the code to clear a return variable in a function. Example:
      C code example
      
      struct {
       unsigned char reg;
       char x1[255];
      } d[4];
      
      char f(unsigned char a, char v) {
          char rc = 0;    // <-- this is optimized away with opt levels > 6
          if (v >= 0) {
              d[a].reg = v;
              rc = 1;
          }
      
          return rc;
      }
      
    • Corrected: a wrong code generation by using the NOAREGS option inside a ISR. This only happens with optimization <= 3. Example:
      C code example
      
      sfr SFRPI = 0xAC;
      
      void Timer1_ISR() interrupt 3
      {
        unsigned char SFRPI_State;
        SFRPI_State=SFRPI; o----------------------------------------------------------+
        SFRPI=SFRPI_State; o----------------------------------------------------+     |
      }                                                                         |     |
                                                                                |     |
      void main() {                                                             |     |
                                                                                |     |
        while(1);                                                               |     |
      }                                                                         |     |
                                                                                |     |
                                                                                |     |
      Generated assembly code                                                   |     |
                                                                                |     |
      0000 C0E0              PUSH    ACC                                        |     |
      0002 C083              PUSH    DPH                                        |     |
      0004 C082              PUSH    DPL                                        |     |
      0006 C0E0              PUSH    ACC    <----- MOV A,R7 missing before PUSH.|     |
                                                                                |     |
                                                                                |     |
      0008 900000      R     MOV     DPTR,#SFRPI_State <------------------------|-----+
      000B E5AC              MOV     A,SFRPI                                    |
      000D F0                MOVX    @DPTR,A                                    |
                                                                                |
                                                                                |
      000E 900000      R     MOV     DPTR,#SFRPI_State <------------------------+
      0011 E0                MOVX    A,@DPTR
      0012 FF                MOV     R7,A
      0013 8FAC              MOV     SFRPI,R7
      
      
      0015 FF                MOV     R7,A   <---- POP ACC missing before MOV R7,A
      0016 D082              POP     DPL          With higher optimization levels
      0018 D083              POP     DPH          ACC is not pushed on the stack
      001A D0E0              POP     ACC          but kept in R7.
      001C 32                RETI
      
      :::::
      
  • [BL51 Linker/Locater]
    • Corrected: BL51 crashed during "Global Register Coloring" optimization if names were too long
  • [LX51 Linker/Locater]
    • Corrected: LX51 SEGSIZE directive changed the segment size but does not shift the segments behind it.
    • Corrected: The linker showed "L48: IGNORED RECURSIVE CALL" also in some cases without any recursion.
  • [A51 Assembler] and [AX51 Assembler]
    • No change.
  • [Device Simulation]
    • s51mx.dll: Erroneously the LOG command enables logging in the debugger only once. This limitation has been corrected.
    • S8051.dll: Erroneously the LOG command enables logging in the debugger only once. This limitation has been corrected.
    • S8051.dll: The caller of a function was not always detected in target mode. This behavior has been corrected.
    • DP51.dll: Corrected a debugger crash when the following ATMEL CPUs: ATID2, ATIE2, 5131, 5132, 51SND1 are used.
  • [Device support]
    • Added support for ML51, ML56, and MS51 devices from Nuvoton.
  • [Target debugging \ Device programmer]
    • Updated: NULink driver to version 3.09.7380r
  • [µVision]
    • This C51 release comes with µVision V5.38.
  • [Supported Operating Systems]
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.