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

assembler rtn called from C

I have the impression that an assembler non-interrupt subroutine called from 'C' need save no registers.

Is that correct?

Erik

Parents
  • The point is the REGUSE control in the assembly code makes a big difference in the C code that calls the assembly code!!

    In the following example the calling C code was reduced by almost 1/2 in size by using REGUSE on the assembly side.

    Main.c
    
    void WithoutRegUse( char C );
    void WithRegUse( char C );
    
    void CallWithoutRegUse( void )
    {
      char i;
      char xdata* p = 0;
      for( i = 0; i != 0x12; ++i, ++p )
        WithoutRegUse(*p);
    }
    
    void CallWithRegUse( void )
    {
      char i;
      char xdata* p = 0;
      for( i = 0; i != 0x12; ++i, ++p )
        WithRegUse(*p);
    }
    
    void main( void )
    {
      CallWithoutRegUse();
      CallWithRegUse();
    }
    Sub.c
    
    #include <reg52.h>
    
    volatile V;
    
    void WithoutRegUse( char C )
    {
      ACC = C;
      #pragma asm
        swap a
        mov  V,a
      #pragma endasm
      return;
    }
    
    #pragma asm
      $reguse _WithRegUse( A, R7 ) 
    #pragma endasm
    void WithRegUse( char C )
    {
      ACC = C;
      #pragma asm
        swap a
        mov  V,a
      #pragma endasm
      return;
    }
    

    Partial Main.lst
    
                 ; FUNCTION CallWithoutRegUse (BEGIN)
                                               ; SOURCE LINE # 7
                                               ; SOURCE LINE # 8
                                               ; SOURCE LINE # 10
    0000 E4                CLR     A
    0001 F500        R     MOV     p,A
    0003 F500        R     MOV     p+01H,A
                                               ; SOURCE LINE # 11
    0005 F500        R     MOV     i,A
    0007         ?C0001:
    0007 E500        R     MOV     A,i
    0009 6412              XRL     A,#012H
    000B 6017              JZ      ?C0004
                                               ; SOURCE LINE # 12
    000D 850082      R     MOV     DPL,p+01H
    0010 850083      R     MOV     DPH,p
    0013 E0                MOVX    A,@DPTR
    0014 FF                MOV     R7,A
    0015 120000      E     LCALL   _WithoutRegUse
    0018 0500        R     INC     i
    001A 0500        R     INC     p+01H
    001C E500        R     MOV     A,p+01H
    001E 70E7              JNZ     ?C0001
    0020 0500        R     INC     p
    0022         ?C0010:
    0022 80E3              SJMP    ?C0001
                                               ; SOURCE LINE # 13
    0024         ?C0004:
    0024 22                RET     
                 ; FUNCTION CallWithoutRegUse (END)
    
                 ; FUNCTION CallWithRegUse (BEGIN)
                                               ; SOURCE LINE # 15
                                               ; SOURCE LINE # 16
                                               ; SOURCE LINE # 18
    ;---- Variable 'p' assigned to Register 'DPTR' ----
    0000 900000            MOV     DPTR,#00H
                                               ; SOURCE LINE # 19
    ;---- Variable 'i' assigned to Register 'R6' ----
    0003 E4                CLR     A
    0004 FE                MOV     R6,A
    0005         ?C0005:
    0005 EE                MOV     A,R6
    0006 6412              XRL     A,#012H
    0008 6009              JZ      ?C0008
                                               ; SOURCE LINE # 20
    000A E0                MOVX    A,@DPTR
    000B FF                MOV     R7,A
    000C 120000      E     LCALL   _WithRegUse
    000F 0E                INC     R6
    0010 A3                INC     DPTR
    0011 80F2              SJMP    ?C0005
                                               ; SOURCE LINE # 21
    0013         ?C0008:
    0013 22                RET     
                 ; FUNCTION CallWithRegUse (END)
    

Reply
  • The point is the REGUSE control in the assembly code makes a big difference in the C code that calls the assembly code!!

    In the following example the calling C code was reduced by almost 1/2 in size by using REGUSE on the assembly side.

    Main.c
    
    void WithoutRegUse( char C );
    void WithRegUse( char C );
    
    void CallWithoutRegUse( void )
    {
      char i;
      char xdata* p = 0;
      for( i = 0; i != 0x12; ++i, ++p )
        WithoutRegUse(*p);
    }
    
    void CallWithRegUse( void )
    {
      char i;
      char xdata* p = 0;
      for( i = 0; i != 0x12; ++i, ++p )
        WithRegUse(*p);
    }
    
    void main( void )
    {
      CallWithoutRegUse();
      CallWithRegUse();
    }
    Sub.c
    
    #include <reg52.h>
    
    volatile V;
    
    void WithoutRegUse( char C )
    {
      ACC = C;
      #pragma asm
        swap a
        mov  V,a
      #pragma endasm
      return;
    }
    
    #pragma asm
      $reguse _WithRegUse( A, R7 ) 
    #pragma endasm
    void WithRegUse( char C )
    {
      ACC = C;
      #pragma asm
        swap a
        mov  V,a
      #pragma endasm
      return;
    }
    

    Partial Main.lst
    
                 ; FUNCTION CallWithoutRegUse (BEGIN)
                                               ; SOURCE LINE # 7
                                               ; SOURCE LINE # 8
                                               ; SOURCE LINE # 10
    0000 E4                CLR     A
    0001 F500        R     MOV     p,A
    0003 F500        R     MOV     p+01H,A
                                               ; SOURCE LINE # 11
    0005 F500        R     MOV     i,A
    0007         ?C0001:
    0007 E500        R     MOV     A,i
    0009 6412              XRL     A,#012H
    000B 6017              JZ      ?C0004
                                               ; SOURCE LINE # 12
    000D 850082      R     MOV     DPL,p+01H
    0010 850083      R     MOV     DPH,p
    0013 E0                MOVX    A,@DPTR
    0014 FF                MOV     R7,A
    0015 120000      E     LCALL   _WithoutRegUse
    0018 0500        R     INC     i
    001A 0500        R     INC     p+01H
    001C E500        R     MOV     A,p+01H
    001E 70E7              JNZ     ?C0001
    0020 0500        R     INC     p
    0022         ?C0010:
    0022 80E3              SJMP    ?C0001
                                               ; SOURCE LINE # 13
    0024         ?C0004:
    0024 22                RET     
                 ; FUNCTION CallWithoutRegUse (END)
    
                 ; FUNCTION CallWithRegUse (BEGIN)
                                               ; SOURCE LINE # 15
                                               ; SOURCE LINE # 16
                                               ; SOURCE LINE # 18
    ;---- Variable 'p' assigned to Register 'DPTR' ----
    0000 900000            MOV     DPTR,#00H
                                               ; SOURCE LINE # 19
    ;---- Variable 'i' assigned to Register 'R6' ----
    0003 E4                CLR     A
    0004 FE                MOV     R6,A
    0005         ?C0005:
    0005 EE                MOV     A,R6
    0006 6412              XRL     A,#012H
    0008 6009              JZ      ?C0008
                                               ; SOURCE LINE # 20
    000A E0                MOVX    A,@DPTR
    000B FF                MOV     R7,A
    000C 120000      E     LCALL   _WithRegUse
    000F 0E                INC     R6
    0010 A3                INC     DPTR
    0011 80F2              SJMP    ?C0005
                                               ; SOURCE LINE # 21
    0013         ?C0008:
    0013 22                RET     
                 ; FUNCTION CallWithRegUse (END)
    

Children