Search code examples
cassembly8051keil

calling assembly routines from c source code in keil ide


I am having delay routines for 8051 micro-controller in assembly language.Ana I can use them in assembly language programs but I want to use these routines from c language as these are generate perfect delay for me.

The code for delay that is delay.asm file I post just beleow...

;ALL DELAYS ROUTINES HERE
DELAY_SEG SEGMENT CODE
RSEG DELAY_SEG
;DELAY OF 1MS SUBROUTINE
DELAY1MS:
     MOV R7,#250
     DJNZ R7,$
     MOV R7,#247
     DJNZ R7,$
     RET
;DELAY OF 100MS SUBROUTINE
DELAY100MS:
     MOV R6,#99;1MUS
L1:
     ACALL DELAY1MS ;99MS
     DJNZ R6,L1;198MUS
     MOV R6,#250;1MUS
     DJNZ R6,$;500US
     MOV R6,#147;1US
     DJNZ R6,$;294US
     NOP
     RET;1US
;DELAY 0F 1SEC SUB ROUTINE
DELAY1S:
     MOV R5,#9
L2:
     ACALL DELAY100MS
     DJNZ R5,L2
     MOV R5,#99
L3:
     ACALL DELAY1MS
     DJNZ R5,L3
     MOV R5,#250
     DJNZ R5,$
     MOV R5,#138
     DJNZ R5,$
     RET

I include this code in assembly language and use simply.But I want to call these routines from c source code.


Solution

  • To properly interface your assembler functions you need to do the following steps:

    • give your module the same NAME as it's file name without extension (I assume that your source file has name delays.a51):
    MODULE DELAYS
    
    • prepend each function name that you want to be visible in C modules with underscore.

    • for each function you need to declare a separate code segment with
      the following naming convention:

    ?PR?FunctionName?ModuleName

    • put each function into it's own segment.
    • also each function name should be made PUBLIC

    Thus, for your DELAY1MS function you have the following:

    ?PR?_DELAY1MS?DELAYS    SEGMENT CODE
        RSEG        ?PR?_DELAY1MS?DELAYS
        PUBLIC      _DELAY1MS
    _DELAY1MS:
        ...
        ...
        RET
    

    To make functions available to the C compiler you should declare them without any mangling (no underscore), so for DELAY1MS you have:

    void Delay1ms(void);

    All this tricky games with names & segments are required for the linker as it builds the graph of calls to allocate memory statically for local variables at link time.