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

new c51 V620c BUG

When I use the new update C51 compiler C51 v620c to translate the following file with SRC directive, the result seems not correct,would keil surport please check it.

#pragma SRC
unsigned int ui_MixedParms(unsigned char ucA,bit btCheck, unsigned int uiB){
  if (btCheck)
    return(ucA + uiB); 
  return(uiB - ucA);		   
}

the produced SRC fileis as follows:

; TST_C_Func2.SRC generated from: TST_C_Func2.c
NAME	TST_C_FUNC2
?PR?_ui_MixedParms?TST_C_FUNC2           SEGMENT CODE 
?DT?_ui_MixedParms?TST_C_FUNC2           SEGMENT DATA OVERLAYABLE 
?BI?_ui_MixedParms?TST_C_FUNC2           SEGMENT BIT OVERLAYABLE 
	PUBLIC	?_ui_MixedParms?BIT
	PUBLIC	?_ui_MixedParms?BYTE
	PUBLIC	_ui_MixedParms

	RSEG  ?DT?_ui_MixedParms?TST_C_FUNC2
?_ui_MixedParms?BYTE:
        uiB?042:   DS   2

	RSEG  ?BI?_ui_MixedParms?TST_C_FUNC2
?_ui_MixedParms?BIT:
    btCheck?041:   DBIT   1
; 
; unsigned int ui_MixedParms(unsigned char ucA,bit btCheck, unsigned int uiB){

	RSEG  ?PR?_ui_MixedParms?TST_C_FUNC2
_ui_MixedParms:
	USING	0
			; SOURCE LINE # 2
;---- Variable 'ucA?040' assigned to Register 'R5' ----
	MOV  	R5,AR7

;   if (btCheck)
			; SOURCE LINE # 4
	JNB  	btCheck?041,?C0001
;     return(ucA + uiB);  
			; SOURCE LINE # 5
	MOV  	A,R5
	MOV  	R6,#00H
	ADD  	A,uiB?042+01H
	MOV  	R7,A
	MOV  	A,R6
	ADDC 	A,uiB?042
	MOV  	R6,A
	RET  	
?C0001:
;   return(uiB - ucA);						   
			; SOURCE LINE # 6
	CLR  	C
	MOV  	A,uiB?042+01H
	SUBB 	A,R5
	MOV  	R7,A
	MOV  	A,uiB?042
	SUBB 	A,#00H
	MOV  	R6,A
; }
			; SOURCE LINE # 7
?C0002:
	RET  	
; END OF _ui_MixedParms

	END

the following line seems not correct,

?_ui_MixedParms?BYTE:
        uiB?042:   DS   2

it should be :

?_ui_MixedParms?BYTE:
        ucA?040:   DS   1
        uiB?042:   DS   2

Are these C51 V620c BUG?

  • The code generated looks correct to me. Remember that the C51 compiler is pretty smart. The ucA argument is passed in R7. The uiB is passed in a fixed memory location. Since uiB is an unsigned int, it requires 2 bytes of storage. And, that's what it gets with

    uiB?042:   DS   2
    

    Jon

  • If you assemble the so generated SRC file and the following ASM file, link them tergether, you will find the result is NOT correct!

    ?PR?MAIN?TST_C_CALL2 SEGMENT CODE
    
      EXTRN CODE (_ui_MixedParms)
      EXTRN DATA (?_ui_MixedParms?BYTE)
      EXTRN BIT  (?_ui_MixedParms?BIT)
    
    RSEG ?PR?MAIN?TST_C_CALL2
    MAIN:
          MOV R7, #0x34
          SETB ?_ui_MixedParms?BIT
          MOV ?_ui_MixedParms?BYTE+01H,#00H
          MOV ?_ui_MixedParms?BYTE+02H,#063H
        LCALL _ui_MixedParms
          MOV A, R7
          MOV B, R6
        SJMP $
    
    CSEG AT 0
    STARTUP:
           LJMP MAIN
    END  
    

    In the C51.pdf Chapter 6:


    Parameter Passing in Fixed Memory Locations

    Parameters passed to assembly routines in fixed memory locations use segments
    named ?function_name?BYTE and
    ?function_name?BIT
    to hold the parameter values passed to the function function_name. Bit parameters are copied into the
    ?function_name?BIT segment
    prior to calling the function. All other parameters are copied into the
    ?function_name?BYTE segment.

    All parameters are assigned space in these segments even if they are passed using registers.

    Parameters are stored in the order in which they are declared in each respective segment.


    Please check if these are new BUG

  • looks like a documentation error, rather than a compiler bug?

    surely this is the way you'd want it to work - why would you want it to allocate RAM space for a parameter it's going to pass in a Register!?

    Note that this is not the correct route to request Keil technical support!
    See the 'Overview' link
    http://www.keil.com/forum/

  • OK, I've just been looking at this:

    C51 v6.14 does behave as described in the manual; ie it does reserve DATA space even for parameters which are passed in registers. This space is wasted, as it is never used - the parameter(s) is(are) in the register(s)!!

    C51 v6.20c does not behave as described in the manual; ie it does not reserve DATA space for parameters which are passed in registers. Thus it only uses DATA space for parameters which will actually use that space.

    So upgrading from C51 v6.14 to v6.20c could well result in a reduction in the amount of DATA space used?

    I don't know if this only applies when using the SRC directive, or if it's the same when compiling straight to .obj?

  • C51 v6.14 does behave as described in the manual; ie it does reserve DATA space even for parameters which are passed in registers. This space is wasted, as it is never used - the parameter(s) is(are) in the register(s)!!

    Uhhh. This is not EXACTLY true. The compiler DOES reserve the space, however, the space is not wasted. In cases where the space is allocated, once inside the function, the register contents are stored in the DATA space. This is pretty much REQUIRED when all registers are used passing arguments to the function. This effectively moves the lengthy code required to initialize the data memory from the function calls to inside the function. This saves program space while wasting a little time (in some cases).

    If you look at the following example:

    long adder (
      long a1,  // Passed in registers
      long a2,  // Passed in fixed memory
      long a3)  // Passed in fixed memory
    {
    return (a1+a2+a3);  // Returned in registers
    }
    
    
    void main (void)
    {
    long x;
    
    x = adder (1234L, 5678L, 12345687L);
    
    while (1);
    }
    

    The first thing the addre function does is to move the a1 data from R4-R7 into its fixed memory space. Ergo, the space is not wasted...

                 ; FUNCTION _adder (BEGIN)
                                               ; SOURCE LINE # 1
    0000 8F00        R     MOV     a1+03H,R7
    0002 8E00        R     MOV     a1+02H,R6
    0004 8D00        R     MOV     a1+01H,R5
    0006 8C00        R     MOV     a1,R4
                                               ; SOURCE LINE # 5
    

    And a total of 16 bytes (4 for main and 12 for adder) of data space are allocated.

    MODULE INFORMATION:   STATIC OVERLAYABLE
       CODE SIZE        =     31    ----
       CONSTANT SIZE    =   ----    ----
       XDATA SIZE       =   ----    ----
       PDATA SIZE       =   ----    ----
       DATA SIZE        =   ----      16
       IDATA SIZE       =   ----    ----
       BIT SIZE         =   ----    ----
    END OF MODULE INFORMATION.
    


    Now, take a look at the following example:

    long adder (
      unsigned b1,  // Passed in registers
      unsigned b2)  // Passed in registers
    {
    return (b1+b2);  // Returned in registers
    }
    
    
    void main (void)
    {
    long x;
    
    x = adder (1234, 5678);
    
    while (1);
    }
    

    In this case, both b1 and b2 are passed in registers, and...

                 ; FUNCTION _adder (BEGIN)
                                               ; SOURCE LINE # 1
    ;---- Variable 'b2' assigned to Register 'R4/R5' ----
    ;---- Variable 'b1' assigned to Register 'R6/R7' ----
                                               ; SOURCE LINE # 4
                                               ; SOURCE LINE # 5
    0000 EF                MOV     A,R7
    0001 2D                ADD     A,R5
    0002 FF                MOV     R7,A
    0003 EE                MOV     A,R6
    0004 3C                ADDC    A,R4
    0005 FE                MOV     R6,A
    0006 E4                CLR     A
    0007 FC                MOV     R4,A
    0008 FD                MOV     R5,A
                                               ; SOURCE LINE # 6
    0009         ?C0001:
    0009 22                RET     
                 ; FUNCTION _adder (END)
    

    No fixed memory locations are used...and furthermore, no fixed DATA space is allocated. Only 4 bytes are allocated for main.

    MODULE INFORMATION:   STATIC OVERLAYABLE
       CODE SIZE        =     31    ----
       CONSTANT SIZE    =   ----    ----
       XDATA SIZE       =   ----    ----
       PDATA SIZE       =   ----    ----
       DATA SIZE        =   ----       4
       IDATA SIZE       =   ----    ----
       BIT SIZE         =   ----    ----
    END OF MODULE INFORMATION.
    

    Jon