ADI_DSP编程时程序相互调用说明及例程

原文地址:http://www.analogcn.com/Article/wz3/200711/20071108162938.html

 

* 下面所陈述的程序之间的调用是基于TigerSharc101处理器,在VisualDSP++3.0上调试通过验证,由于时间仓促,难免有错误。
* VDSP上编程可以使用标准C语言,也可以使用汇编语言。所以,程序之间的调用共分为4种:
* C语言调用C语言子程序
* C语言调用汇编语言子程序
* 汇编语言调用汇编语言子程序
* 汇编语言调用C语言子程序
* 下面详细说明4中调用方法
* 一:C语言调用C语言子程序
* 这种调用方法最简单,和标准C语言调用一样。声明函数之后便可以调用
* 例程:Func调用SubCFunc
*
* void SubCFunc(int *BuffAddr, int N);
* void Func(void)
* {
* int *BuffAddr;
* int N;
* SunCFunc(BuffAddr, N);
* Return;
* }
*
* void SubCFunc(int *BuffAddr, int N)
* {
* return;
* }
*
*
* 二:C语言调用汇编语言子程序
* 这种调用方法最常用。首先要在C语言程序中用extern声明汇编子函数,在汇编子函数中要用
* .global _SunAsmFunc;,这样便可以调用汇编子程序了
* 2.1 声明:
* C语言中声明用 extern void SubAsmFunc(int *BuffAddr, int N);
* 汇编语言中声明 .global _SubAsmFunc;
* 2.2 参数传递
* C语言的参数传递到汇编语言中,
* 地址和整数依次分别用j4, j5, j6, j7传递
* 浮点数依次分别用xr4,xr5, xr6, xr7 传递
* 汇编函数的返回值:
* 浮点值放在xr8中
* 整型值放在j8中
* 多于4个参数的传递则要借助堆栈传递数据。
* 2.3 例程:
* C语言函数:
* extern int SubAsmFunc(int *BuffAddr, float x, int N)
* void CFunc(void)
* {
* int *BuffAddr;
* float x;
* int N;
* SubAsmFunc(BuffAddr, x, N);
* return;
* }
*
* 汇编子程序
* .section program;
* .global _SubAsmFunc;
* _SubAsmFunc:
* //j4存放BufferAddr地址
* //xr5存放浮点数x
* //j6存放N
* //j8返回值存放地址,如果是浮点数则放在xr8中
* _SunAsmFunc.end
* .align_code 4;
* cjmp(np)(abs);nop;nop;nop;;
*
* 三: 汇编程序调用汇编子程序
* 汇编程序调用汇编子程序时,首先要进行堆栈保护,每进一层子函数都要进行堆栈保护
* 在实模式下,堆栈保护使用j26,j27, k26,k27寄存器,编程时不要使用j27:24, 和k27:24
* 寄存器,另外j31和k31寄存器也不可以使用,如果要使用必须把这些寄存器的值做保护。
* 3.1 函数调用声明
* 汇编主程序中声明: .extern _SubAsmFunc;
* 汇编子程序中声明: .global _SubAsmFunc;
* 3.2 参数传递
* 参数传递遵循C语言调用汇编语言规则,但是要在汇编主程序中手动给寄存器赋值
* 3.3 堆栈保护
* 进入一个子程序就要进行堆栈保护,堆栈保护一般定义一个宏来实现,在例程中会
* 详细介绍如何进行堆栈保护。
* 3.4 例程
* 汇编语言调用汇编语言例程,此例程具有通用性,可多层调用,例如可以用C语言调用
* 汇编主程序,再用汇编主程序调用汇编子程序,然后再逐层返回。
* 汇编语言主程序
* #ifndef mENTER
* #define mENTER \
* j26 = j27 - 0x40; k26 = k27 - 0x40;; \
* [j27+=0xFFFFFFF4] = cjmp; k27 = k27 - 0x4;;
* #define mRETRUN \
* cjmp = [j26+0x40];; \
* cjmp(np)(abs); j27:24 = q[j26+0x44]; k27:26 = q[k26+0x44];;
* #endif
* .extern _SubAsmFunc;
* .section program;
* .global _AsmFunc;
* _AsmFunc:
* mENTER;;
* //汇编主程序接收参数传递
* ..........
* ..........
* //汇编主程序调用汇编子程序
* .align_code 4;
* if true, call _SubAsmFunc; q[j27+4] = j27:24; q[k27+4] = k27:24;;
* //接收返回值
* ..........
* mRETURN;;
* _AsmFunc.end:
*
* 汇编语言子程序
* .section program;
* .global _SubAsmFunc;
* _SubAsmFunc:
* mENTER;;
* //参数传递
* ..........
* mRETURN;;
* _SubAsmFunc.end:
*
* 四:汇编程序调用C语言子程序
* 汇编程序调用C语言子程序前要把必要的积存器进行保护,经常保护的寄存器为
* j27:24, k27:24,
* j7:j4, xr7:xr4(如果在继续运行的汇编语言程序中不再使用此寄存器则可以不理会它)
* 汇编语言调用C语言子程序有两种形式
* 4.1 汇编语言调用自定义C语言子程序
* 4.1.1 声明
* 汇编语言主程序声明: .extern _SubCFunc;
* C语言子程序声明: 可以声明,也可以不声明,如果有别的C程序调用此函数
* 则在别的函数中声明即可
* 4.1.2 参数传递
* 参数传递规则同 C语言调用汇编子程序
* j4,j5,j6,j7传递整型参数
* xr4,xr5,xr6,xr7传递浮点参数
* j8返回整型值,
* xr8返回浮点值
* 4.1.3 堆栈保护
* 调用子程序前要先保护 j27:24和k27:24
* 4.2 汇编语言调用VDSP库函数子程序
* 4.2.1 声明
* 汇编语言主程序声明: .extern __cosf; //库函数一般用双下划线 C

语言主控程序中要包含 math.h头文件
* 4.2.2 参数传递
* 参数传递同上
* 4.3 例程
* 汇编语言调用自定义C语言子程序和库函数例程
*
* 主控程序及C语言子程序
* #include <math.h>
* extern int AsmFunc(float a, float b, int N);
*
* void main(void)
* {
* int i;
* int value;
* float a,b;
* int N;
* N = 16;
* a = 10;
* b = 20.5;
* value = AsmFunc(a, b, N);
* while(1)
* {
* i++;
* }
* return;
* }
* //C语言子程序,实现加法
* int SubCFunc(float a, float b, int N)
* {
* int result;
* result = a + b;
* return result;
* }
*
* //汇编语言程序
* #ifndef mENTER
*
* #define mENTER \
* j26 = j27 - 0x40; k26 = k27 - 0x40;; \
* [j27 += 0xFFFFFFF4] = cJMP; k27 = k27 - 0x04;;
* #define mRETURN \
* cjmp = [j26 + 0x40];; \
* cjmp(ABS)(NP); j27:24 = Q[j26 + 0x44]; k27:24 = Q[k26 + 0x44];;
*
* #endif
*
* .extern _SubCFunc;
* .extern __cosf;
* .section program;
* .global _AsmFunc;
* _AsmFunc:
* mENTER;;
* //接收参数并处理
* ................
* //给调用SubCFunc准备参数
* //xr4 = a;;
* //xr5 = b;;
* //j6 = N;;
* .align_code 4;
* if true, call _SubCFunc; q[j27+4] = j27:24; q[k27+4] = k27:24;;
* //接收返回值 保存j8
*
* //给调用cosf准备参数
* //xr4 = 0.5;;
* .align_code 4;
* if true, call __cosf; q[j27+4] = j27:24; q[k27+4] = k27:24;;
* //接收返回值xr8
*
* //汇编程序返回值处理
* ..................
* mRETURN;;
* _AsmFunc.end:
 

你可能感兴趣的:(编程,c,汇编,语言,float,math.h)