go to single .html
[fw/sdcc] / doc / SDCCUdoc-21.html
index 20a79076370a51f7be868d98eb6964ec2eb3b885..142442f1f81228e73ac54073d9a6c76815b242cb 100644 (file)
@@ -1,8 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <HTML>
 <HEAD>
- <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
- <TITLE>SDCC Compiler User Guide: External Stack.</TITLE>
+ <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.7">
+ <TITLE>SDCC Compiler User Guide: Interfacing with assembly routines.</TITLE>
  <LINK HREF="SDCCUdoc-22.html" REL=next>
  <LINK HREF="SDCCUdoc-20.html" REL=previous>
  <LINK HREF="SDCCUdoc.html#toc21" REL=contents>
 <A HREF="SDCCUdoc-20.html">Previous</A>
 <A HREF="SDCCUdoc.html#toc21">Contents</A>
 <HR>
-<H2><A NAME="xstack"></A> <A NAME="s21">21. External Stack.</A> </H2>
+<H2><A NAME="Interface_asm"></A> <A NAME="s21">21. Interfacing with assembly routines.</A> </H2>
 
-<P>The external stack is located at the start of the external ram segment
-, and is 256 bytes in size. When --xstack option is used to compile the program
-, the parameters and local variables of all reentrant functions are allocated
-in this area. This option is provided for programs with large stack space requirements.
-When used with the --stack-auto option, all parameters and local variables
-are allocated on the external stack (note support libraries will need to be
-recompiled with the same options).
-<P>The compiler outputs the higher order address byte of the external ram
-segment into PORT P2, therefore when using the External Stack option, this
-port MAY NOT be used by the application program.
+<H2><A NAME="ss21.1">21.1 Global registers used for parameter passing.</A>
+ </H2>
+
+<P>By default the compiler uses the global registers "DPL,DPH,B,ACC" to pass
+the first parameter to a routine, the second parameter onwards is either allocated
+on the stack (for reentrant routines or --stack-auto is used) or in the internal
+/ external ram (depending on the memory model). 
+<H3>Assembler routine non-reentrant </H3>
+
+<P>In the following example the function<B> cfunc</B> calls an assembler routine
+<B>asm_func</B>, which takes two parameters.
+<P>extern int asm_func( unsigned short, unsigned short);
+<P>
+<PRE>
+int c_func (unsigned short i, unsigned short j) 
+{ 
+        return
+ asm_func(i,j); 
+} 
+int main() 
+{ 
+   return c_func(10,9); 
+}
+</PRE>
+<P>The corresponding assembler function is:-
+<P>
+<PRE>
+        .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
+</PRE>
+<P>Note here that the return values are placed in 'dpl' - One byte return
+value, 'dpl' LSB &amp; 'dph' MSB for two byte values. 'dpl', 'dph' and 'b'
+for three byte values (generic pointers) and 'dpl','dph','b' &amp; 'acc' for
+four byte values.
+<P>The parameter naming convention is <B>_&lt;function_name&gt;_PARM_&lt;n&gt;,</B>
+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 <CODE></CODE><CODE><B>varaible name for
+the second parameter will be _&lt;function_name&gt;_PARM_2.</B></CODE>
+<P>Assemble the assembler routine with the following command.
+<P>
+<PRE>
+asx8051 -losg asmfunc.asm
+</PRE>
+<P>Then compile and link the assembler routine to the C source file with the
+following command,
+<P>
+<PRE>
+sdcc cfunc.c asmfunc.rel
+</PRE>
+<H3>Assembler routine is reentrant </H3>
+
+<P>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.
+<P>extern int asm_func( unsigned short, unsigned short);
+<P>
+<PRE>
+ int c_func (unsigned short i, unsigned short j) reentrant 
+{ 
+       
+ return asm_func(i,j); 
+} 
+int main() 
+{ 
+   return c_func(10,9);
+}
+</PRE>
+<P>The corresponding assembler routine is.
+<P>
+<PRE>
+        .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
+</PRE>
+<P>The compiling and linking procedure remains the same, however note the
+extra entry &amp; 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.
+<H2><A NAME="ss21.2">21.2 With --noregparms option.</A>
+ </H2>
+
+<P>When the source is compiled with --noregparms option , space is allocated
+for each of the parameters passed to a routine.
+<H3>Assembler routine non-reentrant. </H3>
+
+<P>In the following example the function<B> cfunc</B> calls an assembler routine
+<B>asm_func</B>, which takes two parameters.
+<P>
+<PRE>
+extern int asm_func( unsigned short, unsigned short); 
+int c_func (unsigned short i, unsigned short j) 
+{ 
+        return
+ asm_func(i,j); 
+} 
+int main() 
+{ 
+   return c_func(10,9); 
+}
+</PRE>
+<P>The corresponding assembler function is:-
+<P>
+<PRE>
+        .globl _asm_func_PARM_1 
+        .globl _asm_func_PARM_2 
+       
+ .globl _asm_func 
+        .area OSEG 
+_asm_func_PARM_1:       .ds     1 
+_asm_func_PARM_2:      
+ .ds      1 
+        .area CSEG 
+_asm_func: 
+        mov     a,_asm_func_PARM_1
+        add     a,_asm_func_PARM_2 
+        mov     dpl,a 
+        mov    
+ dpl,#0x00 
+        ret
+</PRE>
+<P>Note here that the return values are placed in 'dpl' - One byte return
+value, 'dpl' LSB &amp; 'dph' MSB for two byte values. 'dpl', 'dph' and 'b'
+for three byte values (generic pointers) and 'dpl','dph','b' &amp; 'acc' for
+four byte values.
+<P>The parameter naming convention is <B>_&lt;function_name&gt;_PARM_&lt;n&gt;,</B>
+where n is the parameter number starting from 1, and counting from the left.
+i.e. the <CODE></CODE><CODE><B>left-most parameter name will be _&lt;function_name&gt;_PARM_1.</B></CODE>
+<P>Assemble the assembler routine with the following command.
+<P>
+<PRE>
+asx8051 -losg asmfunc.asm
+</PRE>
+<P>Then compile and link the assembler routine to the C source file with the
+following command,
+<P>
+<PRE>
+sdcc cfunc.c asmfunc.rel
+</PRE>
+<H3>Assembler routine is reentrant. </H3>
+
+<P>In this case the parameters 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.
+<P>extern int asm_func( unsigned short, unsigned short);
+<P>
+<PRE>
+ int c_func (unsigned short i, unsigned short j) reentrant 
+{ 
+       
+ return asm_func(i,j); 
+} 
+int main() 
+{ 
+   return c_func(10,9);
+}
+</PRE>
+<P>The corresponding assembler routine is.
+<P>
+<PRE>
+        .globl _asm_func 
+_asm_func: 
+        push  _bp 
+        mov  _bp,sp
+        mov  a,_bp 
+        clr  c 
+        add  a,#0xfd 
+        mov 
+ r0,a 
+        mov  a,_bp 
+        clr  c 
+        add  a,#0xfc 
+       
+ mov  r1,a 
+        mov  a,@r0 
+        add  a,@r1 
+        mov  dpl,a 
+       
+ mov  dph,#0x00 
+        mov  sp,_bp 
+        pop  _bp 
+        ret
+</PRE>
+<P>The compiling and linking procedure remains the same, however note the
+extra entry &amp; 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.
 <HR>
 <A HREF="SDCCUdoc-22.html">Next</A>
 <A HREF="SDCCUdoc-20.html">Previous</A>