next up previous contents index
Next: 4.5 External Stack Up: 4. SDCC Technical Data Previous: 4.3 <pending: this is   Contents   Index

Subsections

4.4 Interfacing with Assembly Routines

4.4.1 Global Registers used for Parameter Passing

The compiler always uses the global registers DPL,DPH,B and ACC to pass the first parameter to a routine. The second parameter onwards is either allocated on the stack (for reentrant routines or if -stack-auto is used) or in the internal / external ram (depending on the memory model).

4.4.2 Assembler Routine(non-reentrant)

In the following example the function cfunc calls an assembler routine asm_func, which takes two parameters.

extern int asm_func(unsigned char, unsigned char); 
 
int c_func (unsigned char i, unsigned char j) 
{ 
    return asm_func(i,j); 
} 
 
int main() 
{ 
    return c_func(10,9); 
} 
 
The corresponding assembler function is:

.globl _asm_func_PARM_2  
        .globl _asm_func  
        .area OSEG  
_asm_func_PARM_2: 
        .ds 1  
        .area CSEG  
_asm_func:  
        mov a,dpl  
        add a,_asm_func_PARM_2  
        mov dpl,a  
        mov dpl,#0x00  
        ret 
 
Note here that the return values are placed in 'dpl' - One byte return value, 'dpl' LSB & 'dph' MSB for two byte values. 'dpl', 'dph' and 'b' for three byte values (generic pointers) and 'dpl','dph','b' & 'acc' for four byte values.

The parameter naming convention is _<function_name>_PARM_<n>, where n is the parameter number starting from 1, and counting from the left. The first parameter is passed in ``dpl'' for One bye parameter, ``dptr'' if two bytes, ``b,dptr'' for three bytes and ``acc,b,dptr'' for four bytes, the varible name for the second parameter will be _<function_name>_PARM_2.

Assemble the assembler routine with the following command:

asx8051 -losg asmfunc.asm

Then compile and link the assembler routine to the C source file with the following command:

sdcc cfunc.c asmfunc.rel

4.4.3 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. after the call the left most parameter will be on the top of the stack. Here is an example:

extern int asm_func(unsigned char, unsigned char); 
 
int c_func (unsigned char i, unsigned char j) reentrant  
{  
    return asm_func(i,j);  
}  
 
int main()  
{  
    return c_func(10,9);  
} 

The corresponding assembler routine is:

.globl _asm_func  
_asm_func:  
    push _bp  
    mov _bp,sp  
    mov r2,dpl 
    mov a,_bp  
    clr c  
    add a,#0xfd  
    mov r0,a  
    add a,#0xfc 
    mov r1,a  
    mov a,@r0  
    add a,r2 
    mov dpl,a  
    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: 4.5 External Stack Up: 4. SDCC Technical Data Previous: 4.3 <pending: this is   Contents   Index
Johan Knol
2001-07-13