next up previous contents index
Next: 3.15 int (16 bit) Up: 3.14 Interfacing with Assembler Previous: 3.14.3 Assembler Routine (non-reentrant)   Contents   Index

3.14.4 Assembler Routine (reentrant)

In this case the second parameter onwards will be passed on the stack, the parameters are pushed from right to left i.e. before the call the second leftmost parameter will be on the top of the stack (the leftmost parameter is passed in registers). Here is an example:

extern int asm_func(unsigned char, unsigned char, unsigned char) reentrant; 
 
int c_func (unsigned char i, unsigned char j, unsigned char k) reentrant  
{  
    return asm_func(i,j,k);  
}  
 
int main()  
{  
    return c_func(10,9,8);  
}
The corresponding (unoptimized) assembler routine is:

.globl _asm_func  
_asm_func:  
    push _bp  
    mov  _bp,sp      ;stack contains: _bp, return address, second parameter, third parameter 
    mov  r2,dpl 
    mov  a,_bp 
    add  a,#0xfd     ;calculate pointer to the second parameter 
    mov  r0,a  
    mov  a,_bp  
    add  a,#0xfc     ;calculate pointer to the rightmost parameter 
    mov  r1,a  
    mov  a,@r0 
    add  a,@r1 
    add  a,r2        ;calculate the result (= sum of all three parameters) 
    mov  dpl,a       ;return value goes into dptr (cast into int) 
    mov  dph,#0x00  
    mov  sp,_bp  
    pop  _bp  
    ret
The compiling and linking procedure remains the same, however note the extra entry & exit linkage required for the assembler code, _bp is the stack frame pointer and is used to compute the offset into the stack for parameters and local variables.



next up previous contents index
Next: 3.15 int (16 bit) Up: 3.14 Interfacing with Assembler Previous: 3.14.3 Assembler Routine (non-reentrant)   Contents   Index
2008-12-05