Compiler Support on StarCore

8 Calling an Assembly Routine From C Exercise

Practical DSP application commonly use a mixture of C and assembly language. This exercise shows how an assembly language function can be called from C code. The code for this exercise is contained in two files: Ex8.c and addvecs.asm. The C code in Ex8.c calls the assembly language function, addvecs(), in file addvecs.asm, to add two vectors together and return the sum of all the elements of the resultant vector. The prototype for addvecs() is as follows:

short add_vecs

 

 

(

 

 

short x[],

/* Input vector

*/

short y[],

/* Input vector

*/

short z[],

/* Output vector

*/

short length

/* Length of vectors */

);

 

 

Four parameters are passed to addvecs(). The first three are pointers to arrays and are therefore 32-bit values (addresses are 32-bits in StarCore). The fourth parameter is the length of the vectors and is a 16-bit value. The mechanism by which parameters are passed is specified in the application binary interface (ABI). Generally speaking, this ABI specifies the following calling convention:

The first parameter is passed in d0 if it is a numeric scalar or in r0 if it is an address.

The second parameter is passed in d1 if it is a numeric scalar or in r1 if it is an address.

Subsequent parameters are pushed onto the stack.

The return value (if any) is passed back to the calling function in d0 if it is a numeric scalar or in r0 if it is an address.

For simple functions with two parameters or fewer, the stack is not used to pass parameters, and it may be possible to write the entire assembly language function without explicitly using the stack at all. In general, however, the stack is used to pass parameters into the function and to store local variables. Its contents are as shown in Figure 11. Just prior to the function call, parameters 3, 4, 5, and so on are pushed onto the stack (in reverse order), and parameters 1 and 2 are stored in d0/r0 and d1/r1, as described previously. The function is then called, and the return address and status register contents are pushed onto the stack by the jsr or bsr instruction. If the called function modifies register d6, d7, r6, or r7, it should first save them on the stack and then restore them before returning. All other registers are free for use without saving or restoring them. The calling function must save these registers if it needs their values to be preserved. On function exit, the status register contents and return address are popped from the stack (by the rts instruction), and the calling function deallocates the stack space used to pass parameters 3, 4, 5, and so on.

Introduction to the SC140 Tools

23

Page 23
Image 23
Motorola SC140 user manual Calling an Assembly Routine From C Exercise