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

Large memcpy

We are using Keil C-51 V7.06.

There is a structure defined:

typedef struct
{
  unsigned char address_bus_h;
  unsigned char address_bus_l;
  unsigned char data_bus;
}instbus_raw_t;

Using three simple lines to copy the structure to another it enlarges code by 9 bytes, but this is not an elegant solution:

instbus_raw.address_bus_h = instbus_raw_local.address_bus_h;
instbus_raw.address_bus_l = instbus_raw_local.address_bus_l;
instbus_raw.data_bus = instbus_raw_local.data_bus;

Using the normal library function memcpy
blows up the code by 300 bytes!

memcpy(&instbus_raw,&instbus_raw_local,sizeof(instbus_raw_t));

Using an own function my_memcpy the code increases by 167 bytes:

void *(my_memcpy)(void *s1, const void *s2, size_t n)
{
  char *su1 = (char *)s1;
  const char *su2 = (const char *)s2;

  for (; 0 < n; --n)
    *su1++ = *su2++;
  return (s1);
}

my_memcpy(&instbus_raw,&instbus_raw_local,sizeof(struct instbus_raw_t));

In a project with a little chip of 2k Flash, 300 bytes for copying few bytes are considerable!

Does anyone remarking same effects with library functions wasting resources?

Regards Peter

Parents
  • And, of course, you will be needing this:

    compact_memcpy.h:

    #ifndef _COMPACT_MEMCPY_H_
    
    #define _COMPACT_MEMCPY_H_
    
    void *compact_memcpy(void *s1, void *s2, int n);
    
    #endif
    

    And this:

    //
    //  Primary Generic Read
    //
    //  This function reads from a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R1 - low part of address.
    //      R2 - high part of address.
    //      R3 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    //  This function is functionally identical to, and interchangable
    //  with, the comiler function C?CLDPTR.
    //
    
    #pragma ASM
    
    PUBLIC primary_generic_read
    
    ?PR?primary_generic_read   SEGMENT CODE
    
        RSEG  ?PR?primary_generic_read
    
    primary_generic_read:
    
            MOV     A,R3                        ;
            JNB     Acc.0,?pgr_not_dptr         ;
            MOV     DPL,R1                      ;
            MOV     DPH,R2                      ;
            JB      Acc.1,?pgr_not_xdata        ;
            MOVX    A,@DPTR                     ;
            RET                                 ;
    ?pgr_not_xdata:                             ;
            CLR     A                           ;
            MOVC    A,@A+DPTR                   ;
            RET                                 ;
    ?pgr_not_dptr:                              ;
            JNB     Acc.1,?pgr_not_pdata        ;
            MOVX    A,@R1                       ;
            RET                                 ;
    ?pgr_not_pdata:                             ;
            MOV     A,@R1                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    //
    //  Primary Generic Write
    //
    //  This function writes accumulator to a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R1 - low part of address.
    //      R2 - high part of address.
    //      R3 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    
    #pragma ASM
    
    PUBLIC primary_generic_write
    
    ?PR?primary_generic_write   SEGMENT CODE
    
        RSEG  ?PR?primary_generic_write
    
    primary_generic_write:
    
            MOV     B,R3                        ;
            JNB     B.0,?pgw_not_dptr           ;
            MOV     DPL,R1                      ;
            MOV     DPH,R2                      ;
            JB      B.1,?pgw_not_xdata          ;
            MOVX    @DPTR,A                     ;
            RET                                 ;
    ?pgw_not_xdata:                             ;
            RET                                 ;
    ?pgw_not_dptr:                              ;
            JNB     B.1,?pgw_not_pdata          ;
            MOVX    @R1,A                       ;
            RET                                 ;
    ?pgw_not_pdata:                             ;
            MOV     @R1,A                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    //
    //  Auxilliary Generic Read
    //
    //  This function reads from a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R0 - low part of address.
    //      R4 - high part of address.
    //      R5 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    
    #pragma ASM
    
    PUBLIC auxilliary_generic_read
    
    ?PR?auxilliary_generic_read   SEGMENT CODE
    
        RSEG  ?PR?auxilliary_generic_read
    
    auxilliary_generic_read:
    
            MOV     A,R5                        ;
            JNB     Acc.0,?agr_not_dptr         ;
            MOV     DPL,R0                      ;
            MOV     DPH,R4                      ;
            JB      Acc.1,?agr_not_xdata        ;
            MOVX    A,@DPTR                     ;
            RET                                 ;
    ?agr_not_xdata:                             ;
            CLR     A                           ;
            MOVC    A,@A+DPTR                   ;
            RET                                 ;
    ?agr_not_dptr:                              ;
            JNB     Acc.1,?agr_not_pdata        ;
            MOVX    A,@R0                       ;
            RET                                 ;
    ?agr_not_pdata:                             ;
            MOV     A,@R0                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    

Reply
  • And, of course, you will be needing this:

    compact_memcpy.h:

    #ifndef _COMPACT_MEMCPY_H_
    
    #define _COMPACT_MEMCPY_H_
    
    void *compact_memcpy(void *s1, void *s2, int n);
    
    #endif
    

    And this:

    //
    //  Primary Generic Read
    //
    //  This function reads from a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R1 - low part of address.
    //      R2 - high part of address.
    //      R3 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    //  This function is functionally identical to, and interchangable
    //  with, the comiler function C?CLDPTR.
    //
    
    #pragma ASM
    
    PUBLIC primary_generic_read
    
    ?PR?primary_generic_read   SEGMENT CODE
    
        RSEG  ?PR?primary_generic_read
    
    primary_generic_read:
    
            MOV     A,R3                        ;
            JNB     Acc.0,?pgr_not_dptr         ;
            MOV     DPL,R1                      ;
            MOV     DPH,R2                      ;
            JB      Acc.1,?pgr_not_xdata        ;
            MOVX    A,@DPTR                     ;
            RET                                 ;
    ?pgr_not_xdata:                             ;
            CLR     A                           ;
            MOVC    A,@A+DPTR                   ;
            RET                                 ;
    ?pgr_not_dptr:                              ;
            JNB     Acc.1,?pgr_not_pdata        ;
            MOVX    A,@R1                       ;
            RET                                 ;
    ?pgr_not_pdata:                             ;
            MOV     A,@R1                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    //
    //  Primary Generic Write
    //
    //  This function writes accumulator to a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R1 - low part of address.
    //      R2 - high part of address.
    //      R3 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    
    #pragma ASM
    
    PUBLIC primary_generic_write
    
    ?PR?primary_generic_write   SEGMENT CODE
    
        RSEG  ?PR?primary_generic_write
    
    primary_generic_write:
    
            MOV     B,R3                        ;
            JNB     B.0,?pgw_not_dptr           ;
            MOV     DPL,R1                      ;
            MOV     DPH,R2                      ;
            JB      B.1,?pgw_not_xdata          ;
            MOVX    @DPTR,A                     ;
            RET                                 ;
    ?pgw_not_xdata:                             ;
            RET                                 ;
    ?pgw_not_dptr:                              ;
            JNB     B.1,?pgw_not_pdata          ;
            MOVX    @R1,A                       ;
            RET                                 ;
    ?pgw_not_pdata:                             ;
            MOV     @R1,A                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    //
    //  Auxilliary Generic Read
    //
    //  This function reads from a location defined by a generic pointer
    //
    //  The arguments of the generic pointer are as follows:
    //
    //      R0 - low part of address.
    //      R4 - high part of address.
    //      R5 - memory type where:
    //
    //          0x00 - indicates idata memory.
    //          0x01 - indicates xdata memory.
    //          0xFE - indicates pdata memory.
    //          0xFF - indicates code memory.
    //
    
    #pragma ASM
    
    PUBLIC auxilliary_generic_read
    
    ?PR?auxilliary_generic_read   SEGMENT CODE
    
        RSEG  ?PR?auxilliary_generic_read
    
    auxilliary_generic_read:
    
            MOV     A,R5                        ;
            JNB     Acc.0,?agr_not_dptr         ;
            MOV     DPL,R0                      ;
            MOV     DPH,R4                      ;
            JB      Acc.1,?agr_not_xdata        ;
            MOVX    A,@DPTR                     ;
            RET                                 ;
    ?agr_not_xdata:                             ;
            CLR     A                           ;
            MOVC    A,@A+DPTR                   ;
            RET                                 ;
    ?agr_not_dptr:                              ;
            JNB     Acc.1,?agr_not_pdata        ;
            MOVX    A,@R0                       ;
            RET                                 ;
    ?agr_not_pdata:                             ;
            MOV     A,@R0                       ;
            RET                                 ;
    
    #pragma ENDASM
    
    

Children
No data