资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,*,第6章 汇编语言程序设计,6.1 程序的控制与转移,TMS320C54x具有丰富的程序控制与转移指令,利用这些指令可以执行分支转移、循环控制及子程序操作。基本的程序控制指令如表6-1所示。,表6-1 基本的程序控制指令,分支转移指令 执行周期,子程序调用指令 执行周期,子程序返回指令 执行周期,B next 4,BACC src 6,BC next ,cond 5/3,CALL sub 4,CALA src 6,CC sub , cond 5/3,RET 5,RC cond 5/3,1条件算符,条件分支转移指令或条件调用、条件返回指令都用条件来限制分支的转移、调用和返回操作。条件算符分成两组,每组组内还有分类。,第1组:,EQ NEQ,LEQ GEQ,LT GT,OV,NOV,第2组:,TC,NTC,C,NC,BIO,NBIO,选用条件算符时应当注意以下3点:,第1组:组内两类条件可以进行与/或运算,但不能在组内同一类中选择两个条件算符与/或。当选择两个条件时,累加器必须是同一个。例如,可以同时选择AGT和AOV,但不能同时选择AGT和BOV。,第2组:可从组内3类算符中各选一个条件算符与/或,但不能在组内同一类中选两个条件算符与/或。例如,可以同时测试TC、C和BIO,但不能同时测试NTC和TC。,组与组之间的条件只能进行或运算。,2循环操作BANZ,在程序设计时,经常需要重复执行某段程序,利用BANZ(当辅助寄存器不为0时转移)指令执行循环计数和操作是十分方便的。,SUM: STM #x,AR3,STM #4,AR2,loop: ADD *AR3+,A,;程序存储器,BANZ loop,*AR2-,STL A,y,3比较操作CMPR,编程时,经常需要数据与数据进行比较,这时利用比较指令CMPR是很合适的。CMPR指令测试所规定的AR寄存器(AR1AR7)与AR0的比较结果。如果所给定的测试条件成立,则TC位置1,然后,条件分支转移指令就可根据TC位的状态进行分支转移了。注意,所有比较的数据都是无符号操作数。,STM #5,AR1,STM #10,AR0,loop: .,.,*AR1+,.,.,CMPR LT,AR1,BC loop,TC,6.2 堆栈的使用方法,TMS320C54x提供一个用16位堆栈指针(SP)寻址的软件堆栈。当向堆栈中压入数据时,堆栈从高地址向低地址增长。堆栈指针是减在前、加在后,即先SP,1再压入数据,先弹出数据后SP+1。,如果程序中要用到堆栈,则必须先进行设置,方法如下:,size .set 100,stack .usect STK,size,STM #stack+size,SP,上述语句在数据RAM空间开辟一个堆栈区。前两句在数据RAM中自定义一个名为STK的保留空间,共100个单元。第3句将这个保留空间的高地址(#stack+size)赋给SP,作为栈底,参见图6-1。至于自定义未初始化段STK 究竟定位在数据RAM中的什么位置,应当在链接器命令文件中规定。,数据存储器,0,STK,堆栈的设置,size set 100,stack usect STK,size,STM #stack+size,SP,堆栈的用法,压入操作:SP先减1后,再将数据压入堆栈中,弹出操作:数据弹出后,再将SP加1,stack,可用栈区,SP,最后用的单元,已用栈区,65535,图6-1 堆栈,设置堆栈之后,就可以使用堆栈了,例如:,CALL pmad ;(SP)-1SP,(PC)+2TOS,;pmadPC,RET ;(TOS) PC,(SP)+lSP,堆栈区应开辟多大?这需要按照以下步骤来确定:, 先开辟一个大堆栈区,且用已知数填充。, 运行程序,执行所有的操作。, 暂停,检查堆栈中的数值如下图。, 用过的堆栈区才是实际需要的堆栈空间。,1.加减法,【例6-4】计算z=x+y,w。,SUMB: LD x,A,ADD y,A,SUB w,A,STL A,z,RET,.end,计算结果:数据寄存器地址 存储内容 十进制数,x 0060H 000AH 10,y 0061H 001AH 26,w 0062H 0017H 23,z 0063H 000DH 13,6.3 加减法运算和乘法运算,2.乘法,【例6-5】计算y=mx+b。,SU: LD m,T,MPY x,A,ADD b,A,STL A,y,RET,.end,计算结果:数据寄存器地址 存储内容 十进制数,m 0060H 0003H 3,x 0061H 000FH 15,b 0062H 0014H 20,y 0063H 0041H 65,6.4 重复操作,1,重复执行单条指令,重复指令,RPT,或,RPTZ,允许重复执行紧随其后的那一条指令。如果要重复执行,n,次,则重复指令中应规定计数值为,n,1,。由于重复的指令只需要取指一次,与利用,BANZ,指令进行循环相比,效率要高得多。,【例,6-9,】,对数组,x5,0,0,0,0,0,进行初始化。,.bss x,5,或者,STM #x,AR1,LD #0H,A,RPT #4,STL A,*AR1+,或者,.bss x,5,STM #x,AR1,RPTZ #4,STL A,*AR1+,2,块程序重复操作,块程序重复操作,RPTB,将重复操作的范围扩大到任意长度的循环回路。由于块程序重复指令,RPTB,的操作数是循环回路的结束地址,而且,其下条指令就是重复操作的内容,因此必须先用,STM,指令将所规定的迭代次数加载到块重复计数器(,BRC,)中。,RPTB,指令的特点是:对任意长度的程序段的循环开销为,0,,其本身是一条,2,字,4,周期指令;循环开始地址(,RSA,)是,RPTB,指令的下一行,结束地址(,REA,)由,RPTB,指令的操作数规定。,【例,6-10,】,对数组,x5,中的每个元素加,1,。,.bss x,5,start: LD #1,16,B,STM #4,BRC,STM #x,AR4,RPTB next-1,ADD *AR4,16,B,A,STH A,*AR4+,next: LD #0,B,3,循环的嵌套,2nd:,1st:,STM #L,1,AR7 ;2T,外部,STM #M,1,BRC ;2T,RPTB 2nd,1 ;4T,中间,中间,RPT #N,1 ;1T,内部,中间,中间,外部,外部,BANZ 1st,*AR7,;4T,3,1,2,执行,RPT,指令时要用到,RPTC,寄存器(重复计数器),执行,RPTB,指令时要用到,BRC,、,RSA,和,RSE,寄存器。由于两者用了不同的寄存器,因此,RPT,指令可以嵌套在,RPTB,指令中,实现循环的嵌套。当然,只要保存好有关的寄存器,,RPTB,指令也可以嵌套在另一条,RPTB,指令中,但效率并不高。,下图是一个三重循环嵌套结构,内层、中层和外层三重循环分别采用,RPT,、,RPTB,和,BANZ,指令,重复执行,N,、,M,和,L,次。,6.5,数据块传送,这些指令的特点如下:,(1)传送速度比加载和存储指令的速度要快;,(2)传送数据不需要通过累加;,(3)可以寻址程序存储器;,(4)与,RPT,指令相结合,可以实现数据块传送。,数据存储器数据存储器,# W/C,数据存储器,MMR,# W/C,MVDK Smem,dmad,MVKD dmad,Smem,MVDD Xmem,Ymem,2/2,2/2,1/1,MVDM dmad,MMR,MVMD MMR,dmad,MVMM mmr,mmr,2/2,2/2,1/1,程序存储器数据存储器,# W/C,程序存储器(Acc)数据存储器,# W/C,MVPD Pmad,Smem,MVDP Smem,Pmad,2/3,2/4,READA Smem,WRITA Smem,1/5,1/5,1,程序存储器数据存储器,【例,6-11,】,初始化数组,x5=1,2,3,4,5,。,.title,zh9.asm,.mmregs,STACK .usect,STACK,10H,.bss x,5,.data,table: .word 1,2,3,4,5,.def start,.text,start: STM #x,AR1,RPT #4,MVPD table,*AR1+,end: B end,.end,2,数据存储器数据存储器,【例,6-12,】,编写一段程序,将数据存储器中数组,x20,中的数据复制到数组,y20,中。,.title,zh10.asm,.mmregs,STACK .usect,STACK,30H,.bss x,20,.bss y,20,.data,table: .word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,.def start,.text,start: STM #x,AR1,RPT #19,MVPD table,*AR1+ ;从程序存储器传送到数据存储器中,STM #x,AR2,STM #y,AR3,RPT #19,MVDD *AR2+,*AR3+,;从数据存储器传送到数据存储器中,end: B end,.end,20,个数据从,0060H,0073H,传送到,0074H,0087H,,结果如图所示:,6.6,双操作数乘法,TMS320C54x,片内的多总线结构,允许在一个机器周期内通过两条,16,位数据总线(,C,总线和,D,总线)寻址两个数据和系数,如图,6-6,所示。,数据存储器,乘法器/加法器,累加器A,累加器B,C总线,D总线,图6-6 双操作数乘法,如果求,y=mx+b,,则单操作数和双操作数实现方法比较如表,6-4,所示,:,表,6-4,单,/,双操作数编程比较,用双操作数指令编程的特点为:,(1)用间接寻址方式获得操作数,且辅助寄存器只能用,AR2,AR5,;,(2)占用的程序空间小;,(3)运行的速度快。,单操作数方法,双操作数方法,LD m,T,MPY x,A,ADD b,A,STL A,y,MPY *AR2,*AR3,A,ADD b,A,STL A,y,双操作数,MAC,型的指令有,4,种,如表,6-5,所示,:,表,6-5 MAC,型双操作数指令,对于,Xmem,和,Ymem,,只能用以下辅助寄存器及寻址方式:,辅助寄存器,AR2,寻址方式,*ARn,AR3 *ARn+,AR4 *ARn,AR5 *ARn+0%,指 令,功 能,MPY Xmem,Ymem,dst,MAC Xmem,Ymem,src,dst,MAS Xmem,Ymem, src,dst,MACP Smem,Pmad, src,dst,dst=Xmem*Ymem,dst=src+Xmem*Ymem,dst=src-Xmem*Ymem,dst=src+Smem*Pmad,6.7,长字运算和并行运算,1,长字指令,DLD Lmem,dst ;dst=Lmem,DST src,Lmem ;Lmem=src,DADD Lmem,src,dst ;dst=src+Lmem,DSUB Lmem,src,dst ;dst=src-Lmem,DRSUB Lmem,src,dst ;dst=Lmem-src,(,1,)偶地址排列法,(,2,)奇地址排列法,数据存储器,偶地址:xhi,奇地址:xlo,程序存储器,偶地址:1234,奇地址:5678,.long 1 2 3 4 5 6 7 8 h,变量名称,字长,页邻接,偶地址排列法,.bss xhi, 2, 1, 1,图6-8 奇偶地址排列规定,【例,6-15,】,计算,Z,32,=,X,32,+,Y,32,。,标准运算,.title,zh16.asm,.mmregs,STACK .usect,STACK,10H,.bss xhi,1,.bss xlo,1,.bss yhi,1,.bss ylo,1,.bss zhi,1,.bss zlo,1,.def start,.data,table: .word 1678H,2345H,.word 1020H,0D34AH,.text,start: STM #0,SWWSR,STM #STACK+10H,SP,STM #xhi,AR1,RPT #3,MVPDtable,*AR1+,LD xhi,16,A,ADDS xlo,A,ADD yhi,16,A,ADDS ylo,A,STH A,zhi,STL A,zlo,end: B end,.end,(6个字,6个T),长字运算,.title,zh17.asm,.mmregs,STACK .usect,STACK,10H,.bss xhi,2,1,1,.bss yhi,2,1,1,.bss zhi,2,1,1,.def start,.data,table: .long 16782345H,1020D34AH,.text,start: STM #0,SWWSR,STM #STACK+10H,SP,STM #xhi,AR1,RPT #3,MVPD table,*AR1+,DLD xhi,A,DADD yhi,A,DST A,zhi,end: B end,.end,(3个字,3个T),2,并行运算,并行运算指令举例,指 令,举 例,操作说明,LD|MACR,LD|MASR,LD Xmem,dst,|MACR Ymem,dst,2,dst=Xmem(16-ASM),dst=Xmem(16-ASM),dst=dst+T* Xmem,ST|ADD,ST|SUB,ST src,Ymem,|ADD Xmem,dst,Ymem=src(16-ASM),dst=dst+Xmem,【例,6-16,】,用并行运算指令编写计算,z,=,x,+,y,和,f,=,e,+,d,的程序。,.mmregs,STACK .usect,STACK,10H,.bss x,3,.bss d,3,.def start,.data,table: .word 0123H,1027H,0,1020H,0345H,0,.text,start: STM #0,SWWSR,STM #STACK+10H,SP,STM #x,AR1,RPT #5,MVPD table,*AR1+,STM #x,AR5,STM #d,AR2,LD #0,ASM,LD *AR5+,16,A,ADD *AR5+,16,A,ST A,*AR5 ;并行指令,|LD *AR2+,B,ADD *AR2+,16,B,STH B,*AR2,end: B end,.end,3,64,位加法和减法运算,64,位数的加法和减法算式如下:,w3 w2,w1 w0,(W64),+,x3 x2,C,x1 x0,(X64),低32位相加产生进位C,-,y3 y2,C,y1 y0,(Y64),低32位相减产生借位C,z3 z2,z1 z0,(Z64),例6-17编写计算Z64=W64+X64-Y64的程序。,W、X、Y和结果Z都是64位数,它们都由两个32位的长字组成。利用,长字指令,可以完成64位数的加减法。,DLD w1,A ;A=w1w0,DADD x1,A ;A=w1w0+x1x0,产生进位C,DLD w3,B ;B=w3w2,ADDC x2,B ;B=w3w2+x2+C,ADD x3,16,B ;B=w3w2+x3x2+C,DSUB y1,A ;A=w1w0+x1x0-y1y0,产生借位C,DST A,z1 ;z1z0=w1w0+x1x0-y1y0,SUBB y2,B ;B=w3w2+x3x2+C-y2-C,SUB y3,16,B ;B=w3w2+x3x2+C-y3y2-C,DST B,z3 ;z3z2=w3w2+x3x2+C-y3y2-C,数据计算结果,4,32,位乘法运算,32,位乘法算式如下:,x1 x0,S U, y1 y0,S U,x0 y0,UU,y1 x0,SU,x1 y0,SU,y1 x1,SS,w3 w2 w1 w0,S U U U,其中,S带符号数,U无符号数。,由上算式可见,在32位乘法运算中,实际上包括三种乘法运算:UU,SU及SS。一般的乘法运算指令都是两个带符号数相乘,即SS。所以,在编程时,还要用到以下两条乘法指令:,MACSU Xmem,Ymem,src ;无符号数与带符号数相乘并累加,;src=U(Xmem)S(Ymem)+src,MPYU Smem,dst ;无符号数相乘,;dst=U(T)U(Smem),例6-18编写计算W64=X32Y32的程序。,32位乘法实现的64位乘积的程序如下:,STM #x,AR2,STM #y,AR3,LD *AR2,T ;T=x0,MPYU *AR3+,A ;A=ux0uy0,STL A,w0 ;w0=ux0uy0,LD A,-16,A ;A=A16,MACSU *AR2+,*AR3-,A ;A+=y1ux0,MACSU *AR3+,*AR2,A ;A+=x1uy0,STL A,w1 ;w1=A,LD A,-16,A ; A=A16,MAC *AR3,*AR2,A ;A+=x1y1,STL A,w2 ;w2=A的低16位,STH A,w3 ;w3=A的高16位,6.8,小数运算,1,小数的表示方法,TMS320C54x,采用,2,的补码表示小数,其最高位为符号位,数值范围为,1,+1,。一个,16,位的,2,的补码小数(,Q15,格式)的每一位的权值为:,MSB LSB,-1 2,-1,2,-2,2,-3, 2,-15,一个十进制小数乘以,32768,之后,再将其十进制整数部分转换成十六进制数,就能得到这个十进制小数的,2,的补码表示,例如:,1 7FFFH,0.5 正数:乘以32768 4000H,0 0000H,-0.5 负数:其绝对值部分乘以32768,再取反加1 C000H,-1 8000H,在汇编语言程序中,是不能直接写入十进制小数的。若要定义一个系数,0.707,,可以写成:,.word 32768*707/1000,,不能写成,32768*0.707,。,2,小数乘法与冗余符号位,0 1 0 0 (0.5), 1 1 0 1 (-0.375),0 1 0 0,0 0 0 0,0 1 0 0,1 1 0 0 (-0100),1 1 1 0 1 0 0 (-0.1875),一个小数乘法的例子(假设字长4位,累加器8位):,上述乘积是7位,当将其送到累加器时,为保持乘积的符号,必须进行符号位扩展,这样,累加器中的值为11110100(-0.09375),出现了冗余符号位。原因是:,S x x x (Q3格式), S y y y (Q3格式),S S z z z z z z (Q6格式),即两个带符号数相乘,得到的乘积带有2个符号位,造成错误的结果。,解决冗余符号位的办法,:,在程序中设定状态寄存器,ST1,中的,FRCT,(小数方式)位为,1,,在乘法器将结果传送至累加器时就能自动地左移,1,位,累加器中的结果为:,Szzzzzz0(Q7,格式,),,即,11101000(,0.1875),,自动地消去了两个带符号数相乘时产生的冗余符号位。,在小数乘法编程时,应当事先设置,FRCT,位如下:,SSBX FRCT,MPY * AR2,* AR3,A,STH A,Z,这样,,TMS320C54x,就完成了,Q15,Ql5=Q15,的小数乘法。,6.9,除法运算,1,被除数的绝对值小于除数的绝对值,商为小数,在一般的,DSP,中都没有除法器硬件。因为除法器硬件代价很高,所以就没有专门的除法指令。同样,在,TMS320C54x,中也没有一条单周期的,16,位除法指令。但是,利用条件减法指令(,SUBC,指令),加上重复指令“,RPT #15,”,就可实现两个无符号数的除法运算。,条件减法指令的功能如下:,SUBC Smem,src,2,被除数的绝对值大于等于除数的绝对值,商为整数,6.10,浮点运算,1,浮点数的表示方法,在,TMS320C54x,中,浮点数由尾数和指数两部分组成,它与定点数的关系如下:,定点数,=,尾数,2,(,指数),例如,定点数,0x2000(0.25),用浮点数表示时,尾数为,0x4000(0.5),,指数为,1,,即,0.25=0.5,2,1,浮点数的尾数和指数可正可负,均用补码表示。指数的范围为,8,31,。,2,定点数到浮点数的转换,TMS320C54x,通过,3,条指令可将一个定点数转化成浮点数:,(,1,),EXP A,(,2,),ST T,,,EXPONENT,(,3,),NORM A,3,浮点数到定点数的转换,知道,TMS320C54x,浮点数的定义后,就不难将浮点数转换成定点数了。因为浮点数的指数就是在规格化时左移(指数为负时是右移)的位数,所以在将浮点数转换成定点数时,只要按指数值将尾数右移(指数为负时是左移)就行了。,4,浮点乘法举例,【例,6-26,】,编写浮点乘法程序,完成,x,1,x,2,=0.3,(,0.8),运算。,程序中保留,10,个数据存储单元:,x1:被乘数,m2:乘数的尾数,x2:乘数,ep:乘积的指数,e1:被乘数的指数,mp:乘积的尾数,ml:被乘数的尾数,product:乘积,e2:乘数的指数,temp:暂存单元,程序清单如下:,.title zh24.asm,.mmregs,.def start,STACK .usect STACK,100 ;64H,.bss x1,1,.bss x2,1,.bss e1,1,.bss m1,1,.bss e2,1,.bss m2,1,.bss ep,1,.bss mp,1,.bss product,1,.bss temp,1,.data,table: .word 3*32768/10 ;0.3,.word -8*32768/10 ;-0.8,.text,start: STM #STACK+100,SP ;设置堆栈指针,MVPD table,x1 ;将x1和x2传送至数据存储器,MVPD table+1,x2,LD x1,16,A ;将x1规格化为浮点数,EXP A,ST T,e1 ;保存x1的指数,NORM A,STH A,m1 ;保存x1的尾数,LD x2,16,A ;将x2规格化为浮点数,EXP A,ST T,e2 ;保存x2的指数,NORM A,STH A,m2 ;保存x2的尾数,CALL MULT ;调用浮点乘法子程序,end: B end,MULT: SSBX FRCT,SSBX SXM,LD e1,A ;指数相加,ADD e2,A,STL A,ep ;乘积指数ep,LD m1,T ;尾数相乘,MPY m2,A ;乘积尾数在累加器A中,EXP A ;对尾数乘积规格化,ST T,temp ; 规格化时产生的指数temp,NORM A,STH A,mp ;保存乘积尾数在mp中,LD temp,A ;修正乘积指数,ADD ep,A ;(ep)+(temp) ep,STL A,ep ;保存乘积指数在ep中,NEG A ;将浮点乘积转换成定点数,STL A,temp ;乘积指数反号,并且加载到T寄存器,LD temp,T ;再将尾数按T移位,LD mp,16,A,NORM A,STH A,product ;保存定点乘积,RET,.end,
展开阅读全文