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;The corresponding (unoptimized) assembler routine is:
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);
}
.globl _asm_funcThe 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.
_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