calling assembly routines from c source code in keil ide
Question
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.
OTHER TIPS
I don't know about how the interface between your assembler and your C compiler works, but generally you have to tell the assembler to export functions (there should be a directive for that, look at the assembler manual). Normally the functions in assembler need to have an underscore before the name, like _DELAY1S
. Then you need to create an extern
declaration in your source code referencing the function, like
extern void DELAY1S(void);
It may be different for your tools, read the documentation.