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

How to drop unuse code?

I wrote a program compress time to long. But some output give to much ( outout asm ). How can I reduce unuse code. see output below.

my source.

extern unsigned char convBcd2Hex(unsigned char c);

void convert( void )
{
  unsigned long dwTmp;

                      dwTmp =         convBcd2Hex( sClock[YEAR]  ); // 4 year
  _lrol_( dwTmp, 4 ); dwTmp = dwTmp | convBcd2Hex( sClock[MONTH] ); // 4 month
  _lrol_( dwTmp, 5 ); dwTmp = dwTmp | convBcd2Hex( sClock[DAY]   ); // 5 day
  _lrol_( dwTmp, 5 ); dwTmp = dwTmp | convBcd2Hex( sClock[HOUR]  ); // 5 hour
  _lrol_( dwTmp, 6 ); dwTmp = dwTmp | convBcd2Hex( sClock[MINUTE]); // 6 minute
  _lrol_( dwTmp, 6 ); dwTmp = dwTmp | convBcd2Hex( sClock[SECOND]); // 6 second

}
my output list.

                                           ; SOURCE LINE # 140
001F AF00        E     MOV     R7,sClock+06H
0021 120000      R     LCALL   _convBcd2Hex
0024 E4                CLR     A
0025 8F00        R     MOV     dwTmp+03H,R7
0027 F500        R     MOV     dwTmp+02H,A
0029 F500        R     MOV     dwTmp+01H,A
002B F500        R     MOV     dwTmp,A
                                           ; SOURCE LINE # 141
002D AE00        R     MOV     R6,dwTmp+02H
002F AD00        R     MOV     R5,dwTmp+01H
0031 AC00        R     MOV     R4,dwTmp
0033 7804              MOV     R0,#04H
0035 120000      E     LCALL   ?C?LROL
0038 AF00        E     MOV     R7,sClock+05H
003A 120000      R     LCALL   _convBcd2Hex
003D E4                CLR     A
003E EF                MOV     A,R7
003F 4500        R     ORL     A,dwTmp+03H
0041 F500        R     MOV     dwTmp+03H,A
0043 E500        R     MOV     A,dwTmp+02H  +
0045 F500        R     MOV     dwTmp+02H,A  |
0047 E500        R     MOV     A,dwTmp+01H  |-- How can I reduct this code?
0049 F500        R     MOV     dwTmp+01H,A  |
004B E500        R     MOV     A,dwTmp      |
004D F500        R     MOV     dwTmp,A      +
                                           ; SOURCE LINE # 142
004F AF00        R     MOV     R7,dwTmp+03H
0051 AE00        R     MOV     R6,dwTmp+02H
0053 AD00        R     MOV     R5,dwTmp+01H
0055 FC                MOV     R4,A
0056 7805              MOV     R0,#05H
0058 120000      E     LCALL   ?C?LROL
005B AF00        E     MOV     R7,sClock+04H
005D 120000      R     LCALL   _convBcd2Hex
0060 E4                CLR     A
0061 EF                MOV     A,R7
0062 4500        R     ORL     A,dwTmp+03H
0064 F500        R     MOV     dwTmp+03H,A
0066 E500        R     MOV     A,dwTmp+02H  +
0068 F500        R     MOV     dwTmp+02H,A  |
006A E500        R     MOV     A,dwTmp+01H  |-- How can I reduct this code? 
006C F500        R     MOV     dwTmp+01H,A  |
006E E500        R     MOV     A,dwTmp      |
0070 F500        R     MOV     dwTmp,A      +

Parents
  • Even the best compilers will generate some unnecessary code - it can be very frustrating especially if you come from an assembly language background.

    You are not using _lrol_ in quite the right way, although that is not the root of your question. It looks like the compiler is casting the return value of convBcd2Hex() an insists on "going through the motions" when performing an OR.

    Have you tried using a union between a long and a structure with bit fields defined for each of the components year, month day... etc. It would look something like this:

    typedef struct
    {
        unsigned char   year   :5
        unsigned char   month  :4
        unsigned char   day    :5
        unsigned char   hour   :6
        unsigned char   minute :6;
        unsigned char   second :6;
    
    } date_time_record_type;
    
    typedef union
    {
        unsigned long          l;
        date_time_record_type  t;
    } date_time_type;
    
    ....
    date_time_type dwTmp;
    ....
    dwTmp.t.month = convBcd2Hex( sClock[MONTH] );
    .... 
    
    This way, C will do all the necessary rolling etc. with the programmer having to worry about it. With any luck, Keil will generate more efficient code this way.

    For a faster version of _lrol_ see:

    http://www.keil.com/forum/msgpage.asp?MsgID=4857

Reply
  • Even the best compilers will generate some unnecessary code - it can be very frustrating especially if you come from an assembly language background.

    You are not using _lrol_ in quite the right way, although that is not the root of your question. It looks like the compiler is casting the return value of convBcd2Hex() an insists on "going through the motions" when performing an OR.

    Have you tried using a union between a long and a structure with bit fields defined for each of the components year, month day... etc. It would look something like this:

    typedef struct
    {
        unsigned char   year   :5
        unsigned char   month  :4
        unsigned char   day    :5
        unsigned char   hour   :6
        unsigned char   minute :6;
        unsigned char   second :6;
    
    } date_time_record_type;
    
    typedef union
    {
        unsigned long          l;
        date_time_record_type  t;
    } date_time_type;
    
    ....
    date_time_type dwTmp;
    ....
    dwTmp.t.month = convBcd2Hex( sClock[MONTH] );
    .... 
    
    This way, C will do all the necessary rolling etc. with the programmer having to worry about it. With any luck, Keil will generate more efficient code this way.

    For a faster version of _lrol_ see:

    http://www.keil.com/forum/msgpage.asp?MsgID=4857

Children
No data