对于微处理器来说,每隔一周期即可进入1条新指令,这样在同一时间内,就有多条指令交替地在不同部件内处理,这种工作方式称为“流水线”(pipeline)工作方式。即取指、译指、执行同时进行。
short pa[10] = {0}, pb[10] = {0};
void main()
{
int i = 0,sum = 0;
for(i=0; i< 10; i++)
{
sum +=pa[i]*pb[i];
}
}
SP表示基址
80001BA0 07BD09C2 SUB.D2 SP,0x8,SP 指针入栈
80001BA4 01800040 MVK.D1 0,A3 0送入通用寄存器A3
80001BA8 01BC22F5 STW.D2T1 A3,*+SP[0x1] 将A3内容送入[SP+4]=0(i = 0)
80001BAC 0200002A || MVK.S2 0x0000,B4 0送入通用寄存器B4
80001BB0 023C42F6 STW.D2T2 B4,*+SP[0x2] 将B4的内容送入[SP+8]=0(sum = 0)
80001BB4 00002000 NOP 2 二周期空操作
80001BB8 02000042 MVK.D2 0,B4 0送入B4
80001BBC 001148DA CMPGT.L2 10,B4,B0 比较10和B4的大小,结果送入B0
80001BC0 30178120 [!B0] BNOP.S1 L2,4 若B0为0,跳转到L2执行
80001BC4 023C22F6 STW.D2T2 B4,*+SP[0x1] 将B4送入内存[SP+4]=0
80001BC8 L1:
80001BC8 019018F1 OR.D1X 0,B4,A3 //B4与0“或”结果送入A3
80001BCC 0280CC2B || MVK.S2 0x0198,B5 //B5=0x0198
80001BD0 0200D828 || MVK.S1 0x01b0,A4 //A4=0x01b0
80001BD4 02389AB1 ADD.D1X A4,DP,A4
80001BD8 02B8A842 || ADD.D2 DP,B5,B5
80001BDC 01906A45 LDH.D1T1 *+A4[A3],A3 //A3=pb[A3]
80001BE0 02148AC6 || LDH.D2T2 *+B5[B4],B4 //B4=pa[B4]
80001BE4 00002000 NOP 2
80001BE8 02BC42E6 LDW.D2T2 *+SP[0x2],B5 //去sum放入B5
80001BEC 00000000 NOP
80001BF0 01907C80 MPY.M1X A3,B4,A3 //
80001BF4 00002000 NOP 2
80001BF8 020CBAB2 ADD.D2X B5,A3,B4 //sum = pa[i]*pb[is]
80001BFC 023C42F6 STW.D2T2 B4,*+SP[0x2] //结果sum存入[SP+8]
80001C00 00002000 NOP 2
80001C04 023C22E6 LDW.D2T2 *+SP[0x1],B4 //令B4 = i
80001C08 00006000 NOP 4
80001C0C 02102942 ADD.D2 B4,0x1,B4 //完成i++功能
80001C10 001148DA CMPGT.L2 10,B4,B0//比较10和B4,大小结果放入B0
80001C14 2FF28120 [ B0] BNOP.S1 L1,4 //若10>i继续循环L1
80001C18 023C22F6 STW.D2T2 B4,*+SP[0x1] //且i值存入[SP+4]
80001C1C L2:
80001C1C 008C8362 BNOP.S2 B3,4
80001C20 07BD0942 ADD.D2 SP,0x8,SP //SP指针出栈
80001C24 00000000 NOP
80001C28 00000000 NOP
80001C2C 00000000 NOP
80001C30 00000000 NOP
80001C34 00000000 NOP
80001C38 00000000 NOP
80001C3C 00000000 NOP
中断向量表设置:
用C语言编写的中断服务程序主要由以下四步组成:
(1)选择中断源并编写中断服务程序(interrupt service routine);
(2)创建并初始化中断向量表(interrupt vectortable);
(3)通过设置相关中断控制寄存器来使能中断;
(4)通过编写连接器命令文件(linker commandfile)来完成程序各个段的连接。
C程序的基本结构:
1. 主程序main.c C程序的入口点
2. 链接命令文件.cmd
这个文件包含了DSP和目标板的存储器空间的定义,以及数据段,代码段是如何分配到这些空间的。
3. C运行库文件rst6000.lib
如果用户程序是准备写进EPROM并在上电后运行,则还要包括.asm文件,该文件的代码将作为IST(中断服务表),并且必须被.cmd文件分配在地址0。DSP在复位后首先跳转到0地址,执行复位中断,而该复位中断对应的代码要跳转到_c_int00函数,来完成诸如堆栈的初始化,全局变量等操作,接着执行用户main()函数。
全局变量和静态变量被分配在.bss段中,并且在小模式下,.bss段要小于32k,也就是说程序成定义的全局变量和静态变量所占用的空间不能超过32k。对变量采用直接寻址,而在大模式下没有限制,对变量的访问采用间接寻址,速度较慢。
C程序与线性汇编的混合编程:
在后缀名为.sa的文件中书写线性汇编程序如下:
.global _add2 ;申明全局函数add2
_add2: .cproc a,b ;.cproc与.endproc标明这之间是汇编优化器所处理的内容
.reg sum ;
ADD a,b,sum ;sum = a + b
.return sum ;
.endproc ;
C调用
int add2(int ai, int bi);
main()
{
int c_result = add2(1,2);
printf(“The add result = %d”, c_result);
}
关键字volatile的使用:
1. 汇编语言对volatile的解释
main()
{
int nsize_t = 0;
int nsize_l = nsize_t;
}
SUB.D2 SP,0x8,SP
MVK.D2 0,B4
STW.D2T2 B4,*+SP[0x1]
NOP 2
STW.D2T2 B4,*+SP[0x2];没有取地址操作数
NOP 2
main()
{
volatile int nsize_t = 0;
int nsize_l = nsize_t;
}
SUB.D2 SP,0x8,SP
MVK.D2 0,B4
STW.D2T2 B4,*+SP[0x1]
NOP 2
LDW.D2T2 *+SP[0x1],B4;取地址操作数
NOP 4
STW.D2T2 B4,*+SP[0x2]
NOP 2