实验三 C54X的浮点数的算术运算.doc_第1页
实验三 C54X的浮点数的算术运算.doc_第2页
实验三 C54X的浮点数的算术运算.doc_第3页
实验三 C54X的浮点数的算术运算.doc_第4页
实验三 C54X的浮点数的算术运算.doc_第5页
免费预览已结束,剩余26页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验三、C54X的浮点数的算术运算1 实验目的(1) 练习TMS320C54X汇编程序的编写与调试方法,重点练习C54X程序流程控制的方法。(2) 学习并掌握应用TMS320C54X来进行浮点数的各种算术运算的算法实现。(3) 练习并掌握TMS320C54X的汇编语言的汇编指令系统的使用方法,重点练习具有C54X特点的一些在功能上有所扩展的特殊指令,并了解这些指令在进行算术运算或各种控制时所带来的方便。(4) 练习并掌握用CCS调试程序的一些基本操作。2 实验原理(1) 浮点数的表示方法在定点运算中,小数点是在一个特定的固定位置。例如,如果一个32-bit的数把小数点放在最高有效位(也就是符号位)之后,那么就只有分数(绝对值小于1)才能被显示。在定点运算系统中,虽然在硬件上实现简单,但是表示的操作数的动态范围要受到限制。使用浮点数,可以避免这个困难。一个浮点数由尾数m、基数b和指数e三部分组成。即: 下图举例说明了IEEE标准里的浮点数表示方法。这个格式用带符号的表示方法来表示尾数,指数含有127的偏移。在一个32-bit表示的浮点数中,第一位是符号位,记为S。接下来的8-bit表示指数,采用127的偏移格式(实际是e-127)。然后的23-bit表示尾数的绝对值,考虑到最高一位是符号位,它也应归于尾数的范围,所以尾数一共有24-bit 1 8 23SBiased Exponent -eMantissa -f通常用该格式所表示的浮点数值如下:在特殊情况下:比如说:十进制数-29.625可以用二进制表示为-11101.101B,用科学计数法表示为 -1.1101101*24,其指数为127+4=131,化为二进制表示为10000011B,故此数的浮点格式表示为11000001111011010000000000000000,转换成16进制表示为0xC1ED0000。又如在下面程序中将要使用的浮点数12.0,用二进制表示为1100B,用科学记数法表示为1.1*23,其指数部分为127+3=130,化为二进制表示为10000010B,因此该数的浮点数格式为01000001010000000000000000000000,转换成16进制表示为0x41400000。浮点数144.0,用二进制表示为10010000B,科学记数法记为1.001*27,指数部分为127+7=134=10000110B,该数的浮点数格式为01000011000100000000000000000000,转换成16进制表示为41300000H。(2) 浮点数运算的步骤 加法的运算步骤要在C54X上实现浮点运算,操作数必须变换成定点数,实际上就是一个数据格式的转换问题,可以用以下代码段来实现:dldop1_hsw,a;将OP1装入累加器A中。sftaa,8sftaa,-8;通过先左移后右移使 AG = 0。bcop1_zero,AEQ;如果OP1是零,转入特殊处理。stha,-7,op1se;将符号和指数存储到OP1SE中。stla,op1lm;存储尾数的低位。and#07Fh,16,a;将浮点数格式中的符号和指数去掉得到尾数的高位。add#080h,16,a;给尾数加上小数点前的“1”。stha,op1hm;存储尾数的高位。执行完这段代码之后,操作数1就从原来在op1_hsw和op1_lsw(共32bit)中的浮点数格式转换为三部分:指数和符号位(存储于op1se中)、尾数低位(存储于op1lm中)以及尾数高位(存储于op1hm中),这时所有的数值就都转换为定点数的格式了。在上述程序段中执行了sftaa,8sftaa,-8它是先把累加器A中的值作算术左移8位再算术右移8位,其结果是使累加器A中的8位保护位(bit39-bit32)全清为0以免对以后的运算产生错误影响。注意上述代码中使用了一种双精度的寻址方式,指令为:dldop1_hsw,a;它受st1中的C16位的影响,在C16=0的情况下采用双精度的寻址方式,把op1_hsw以及紧跟其后的一个字节的数据(op1_lsw)一起作为一个32bit的数装入累加器A中。在C16=1的情况下该指令把op1_hsw和op1_lsw作为两个16bit的数装入累加器A中,op1_hsw装在AH中,op1_lsw装在AL中。使用该指令比较有效,只需用一个时钟周期就可以装入32bit的数,这就比分步来装入要节约空间和时间。在这段程序中作了一个判断以提高程序运行的效率:当op1是零时就执行相对应的特殊处理程序段op1-zero:op1_zero:return_op2:bdreturn_value;延迟跳转dldop2_hsw,a;将OP2 作为结果装入acc A中执行该段程序即可快速的返回op2的值。这段程序在后面判断完op2远大于op1之后也将被调用来返回op2的值。由于实行的是带符号位的运算,所以要把尾数变成带符号的形式,即如果是正数就不改变其存储格式,而如果是负数,就要用补码来表示尾数,这部分的代码如下:bitfop1se,#100h;取出op1符号位的值于TC位中bctestop2,NTC;如果TC = 0则跳转到testop2处ld#0,a;dsubop1hm,a;0 op1的尾数,得到尾数的补码表示dsta,op1hm;将尾数存入op1hm和op1lm中testop2:bitfop2se,#100h;取出op1符号位的值于TC位中bccompexp,NTC;如果TC = 0则跳转到compexp处ld#0,a;dsubop2hm,a;0 op1的尾数,得到尾数的补码表示dsta,op2hm;将尾数存入op1hm和op1lm中通过上述过程,把浮点数分解为尾数和指数两个部分,对于浮点数的加法而言,计算过程是左移指数较小的操作数的尾数,使得两个操作数的指数一致,相差几位移几位,再把尾数相加,归一化后输出。主要是要比较两个操作数指数的大小,这样才能决定到底是尾数直接相加还是移位以后再相加,该段过程可以用以下的代码来实现:compexp:ldop1se,a;将操作数1的符号和指数位装入acc A中and#00ffh,a;去掉符号位的影响ldop2se,b;将操作数2的符号和指数位装入acc B中and#00ffh,a;去掉符号位的影响suba,b;op2的指数 - op1的指数结果赋给acc Bbcop1_gt_op2,BLT;跳到进行 op1 op2的操作处bcop2_gt_op1,BGT;跳到进行 op2 op1的操作处a_eq_b:;执行A = B的操作dldop1hm,a;将操作数1的尾数(32bit)放到acc A中daddop2hm,a;将操作数2的尾数与操作数1的尾数进行32bit的双精;度加法bcres_zero,AEQ;如果结果零就转入专门处理过程ldop1se,b;将指数装入acc B中以准备规一化处理这里又有一个特殊的处理程序:结果是零的情况。当这种情况发生时,处理很简单,只需如下几步就可以完成处理:res_zero:bdreturn_value;延迟跳转suba,a;acc A中清零处理。nop在以上的程序中比较了OP1和OP2的指数,需要注意的是,在比较完指数大小之后如果OP1的指数比较大就执行op1_gt_op2段代码,在这段代码中以OP1为基准,左移次数较低的OP2的尾数,使OP2的指数与OP1的指数一致,具体程序如下:op1_gt_op2:absb;去掉符号位的影响sub#24,b;判断op1_se是否比op2_se大24bcreturn_op1,BGEQ;如果op1_se远远大于op2_se则转入相应的返回op1的;操作add#23,b;恢复指数的差值stlb,rltsign;存储指数差值以准备作为RPC使用dldop2hm,a;将OP2的尾数(32bit)装入acc A中rptrltsign;规范OP2以适应OP1sftaa,-1bdnormalize;延迟方式执行跳转到normalize 处ldop1se,b;将指数值装入acc B以准备规一化处理daddop1hm,a;将 OP1和OP2的尾数相加该段代码使用指令rptrltsignsftaa,-1来实现了对OP2的尾数的移位操作。rpt指令执行的循环次数由rltsign中的值决定,当rltsign中的值为N时,sfta指令就执行N+1次,所以B累加器中的值在先减去24以后只需要加23就可以装入rltsign中了。该段程序中还有一个需要值得注意的是使用了延迟指令:bdnormalize;延迟方式执行跳转到normalize 处ldop1se,b;将指数值装入acc B以准备规一化处理daddop1hm,a;将 OP1和OP2的尾数相加bd 指令表示紧接着该指令的后面两条单字指令:ld、dadd都要从程序存储器中取出先执行。这段程序执行完后,程序跳到normalize段,并且acc B中值为op1se中的值,acc A中的值为OP1和OP2的尾数的和(用双精度加法实现)。完成对操作数之间的计算后就需要对结果数进行归一化操作。所谓归一化操作就是把数据格式转换为第一位为符号位,紧接着的一位是非零的数的格式,即是:S1xxxxxxxxxxxxxx的形式。可以用如下的代码来实现:normalize:stha,rltsign;将带符号的尾数高位存入rltsign单元中absa;去掉符号位的影响sftla,6;进行归一化的预处理,将acc中的值左移6位expa;对acc A中的值进行规一化操作normastt,rltexp;存储规一化时左移的数值到rltexp中add#1,b;考虑到进位位所以要给指数加上“1”subrltexp,b;完成指数的归一化工作normalized:stlb,rltexp;将结果指数存在rltexp中bcunderflow,BLEQ;如果B 0 进行下溢处理sub#0ffh,b;进行上溢处理判断bcoverflow,BGEQ;如果B 0 进行上溢处理sftla,-7;将尾数右移7位以方便以后合成为32bit的浮点数格式stla,rltlm;存储低位的尾数and#07f00h,8,a;将最开始中小数点前的“1”省略stha,rlthm;存储高位的尾数在这段代码中acc A中的值是由两个24bit的操作数定点相加而得到的,其MSB可能在bit24-bit0中的任何一位,所以首先左移6位让bit24移至bit30,接下来通过:expanorm a来归一化acc A中的数据,exp和norm指令联合使用之后acc A中的数据变成归一化形式。比如:这两条指令执行之前acc A中的值为0x01800000,执行以后A中的值为0x60000000。操作数左移的位数被存于寄存器T中,如上述操作后寄存器T中的值为0x0006,所以最后的指数的计算还要减去寄存器T中的值才是最后结果的指数值。归一化完后要再把归一化后的定点数转变为浮点数,这是前面的转变浮点数为定点数的逆过程,参照前述步骤可以用如下程序实现:;- Conversion of Floating Point Format to Pack -ldrltsign,9,a;将rltsign左移9位后acc A中and#100h,16,a;取出rltsign中的符号位,使acc A中的格式为;0000 000S 0000 0000 0000 0000 0000 0000addrltexp,16,a;将结果的指数存入acc A中满足浮点数格式的相应位置;A中格式为:0000 000S EEEE EEEE 0000 0000 0000 0000sftla,7;A中格式为:SEEE EEEE E000 0000 0000 0000 0000 0000daddrlthm,a;最终在acc A中得到32位的浮点数格式如下:;SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM这样综合上述的各个步骤,加法运算就可以实现了 。 减法的运算步骤减法运算的实现与加法运算几乎完全一样,只是在具体进行运算时使用的是减法指令而不是加法指令。比如要进行的是被减数(OP3)与减数(OP4)的减法运算。首先是转换数据格式,这一步与加法运算中的过转换程完全一样,在此就不再赘述了。然后要进行的是指数比较判断、尾数移位对齐小数点后相减的操作,该部分程序代码如下:ldop3se,a;将操作数3的符号和指数位装入acc A中and#00ffh,a;去掉符号位的影响ldop4se,b;将操作数4的符号和指数位装入acc B中and#00ffh,b;去掉符号位的影响suba,b;op4的指数 op3的指数结果赋给acc Bbcop3_gt_op4,BLT;进行 op3 op4的操作bcop4_gt_op3,BGT;进行op4 op3的操作a_eq_b:;执行A = B的操作dldop3hm,a;将操作数3的尾数(32bit)放到acc A中dsubop4hm,a;将操作数4的尾数与操作数1的尾数进行32bit的双精;度减法ldop3se,b;将指数装入acc B中以准备规一化处理在这段程序中比较了OP3和OP4的指数,需要注意的是,在比较完指数大小之后,如果OP4的指数比较大就执行op4_gt_op3段代码,在这段代码中以OP4为基准,左移次数较低的OP3的尾数,使OP4的指数与OP3的指数一致,具体程序如下:op4_gt_op3:sub#24,b;判断op4_se是否比op3_se大24bcreturn_op4,BGEQ;如果op4_se远远大于op3_se则转入相应的返回op4的 ;操作add#23,b;恢复指数的差值stlb,rltsign;存储指数差值以准备作为RPC使用dldop3hm,a;将OP3的尾数(32bit)装入acc A中rptrltsign;规范OP3以适应OP4sftaa,-1bdnormalize;延迟方式执行跳转到normalize 处ldop4se,b;将指数值装入acc B以准备规一化处理dsubop4hm,a;将 OP4和OP3的尾数相减完成对操作数之间的计算后就需要对结果数进行归一化,之后转变为浮点数存储。该过程与浮点数加法运算的归一化存储过程完全一样,读者可以参照前面的程序段编写出这部分的代码。 乘法的运算步骤当两个数相乘时,编程的大体框架还是与加减法一样的。同样要经过分离指数和尾数,进行算术运算,以及最后的归一化存储这几个过程,只是运算时要遵循乘法运算的规则把指数相加,尾数相乘。需要注意的是,由于C54X的乘法器在一个指令周期内只能完成17bit*17bit的二进制补码运算,故相乘运算需要分步实现,具体原理如下:设是对两个数OP5和OP6进行乘法运算。将被乘数数OP5的尾数分为Q,R和S三部分,Q表示尾数的高位的8bit,R和S表示尾数低位的两字节。同样,乘数OP6也被分为X,Y和Z三部分,X表示尾数的高位,Y和Z表示尾数低位的两字节。于是有需要注意的是,进行的这种32bit*32bit的运算是有精度损失的。如上图所示,32位数0QRS乘以32位数0XYZ所得的结果应该是一个64bit的值。由于0Q*0X的高16bit始终为0,所以结果可以用一个48位的值准确表示。但是用于存储结果的存储单元长度只有32bit,于是只有将最低的16bit省略掉,即把RS*YZ的低16bit略去,因此最后得到的是一个有精度损失的32bit结果。由于进行的是带符号的运算,所以在进行相乘运算时首先要确定最后结果的符号位。根据“同号为正,异号为负”的原则,可以写出以下代码:;- sign evaluation -ldop5se,a;装入op5的指数和符号位xorop6se,a;与op6的指数和符号位相异或and#00100h,a;屏蔽指数得到符号位stla,rltsign;得到结果的符号位具体相乘的步骤可以用如下代码来实现,首先进行指数位的相加:;- exponent summation -ldop5se,aand#00FFh,a;去掉符号位的影响ldop6se,band#00FFh,b;去掉符号位的影响sub#07fh,b;op6的指数减去127(避免结果加上两个127偏移)addb,a;加上op5的指数stla,rltexp;将指数结果存于rltexp中bcunderflow,ALT;如果exp 255则跳转到下溢处理overflow处然后对尾数运用上面的公式进行运算:ld op5lm,t;将OP5的低位尾数装入T寄存器mpyu op6lm,a;RS*YZmpyu op6hm,b;RS*0Xadda,-16,b;B=(RS*YZ)+(RS*0X)ld op5hm,t;将OP5的高位尾数装入T寄存器mpyu op6lm,a;A=0Q*YZaddb,a;A=(RS*YZ)+(RS*0X)+(0Q*YZ)mpyu op6hm,b;B=0Q*0Xstl b,rlthm;得到0Q*0X的低16bitaddrlthm,16,a;A=最后的结果 值得注意的是,该段代码中使用了mpyu指令,该指令将T寄存器中的值看作一个无符号数与无符号的单数据存储器操作数相乘,将结果放于指定的累加器中。这条指令在执行这种多精度乘法运算时相当有效。同加法减法一样,乘法运算同样会产生上溢出和下溢出的情况,当上溢出发生,即指数部分的值大于254时,就需要进行相应的上溢出的处理工作,具体的程序如下:overflow:st#2,errno;将出错位置以相应的表示位ldrltsign,16,b;将符号位装入acc B中ld#0FFFFh,a;下溢出的结果低位为 0FFFFhorb,7,a;;Add sign bitbdreturn_value;延迟跳转add#07F7Fh,16,a;将结果的指数置为0FEh且把尾数的高7位bit全置为零当下溢出情况发生,即指数部分的值小于等于0时,执行下溢出处理的程序如下:underflow:st#1,errno;将出错位置以相应的表示位bdreturn_value;延迟跳转suba,a;对于下出溢结果= 0nop 除法的运算步骤除法运算的实现与乘法运算差不多,同样要经过分离指数和尾数,估计结果的符号位,对指数进行相减运算,对尾数进行相除运算,以及最后的归一化存储这几个过程。不同的是,在执行除法运算的时候,需要将除数和被除数都由24bit左移成32bit的形式,以减少误差。设是对两个数OP7和OP8进行除法运算,被除数OP7左移后被分为OP7HI(高16bit),OP7LO(低16bit)两部分,除数OP8左移后被分为OP8HI(高16bit),OP8LO(低16bit)两部分,设结果被分为QHI(高16bit)和QLO(低16bit)两部分,于是就有设X = OP8LO/OP8HI ,由泰勒展开式可知:在进行数学计算时,x的平方以后的项可以忽略,即可以用1 x代入式中进行计算,故有:这就是用DSP进行除法运算的公式。根据这个公式,可以写出有关除法运算的代码: dldop7hm,a;;将被除数装入acc A中sftla,6;将被除数左移为除法作准备,因为SUBC要求被除数最高;位为0,且被除数要小于除数故只移6位dldop8hm,b;将除数装入acc B中sftlb,7;将除数左移为除法作准备,因为SXM1,故要求最高;位为零,只移7位dstb,op8hm;将除数存于op8hm和op8lm中rpt#14;QHI=OP7HI/OP8HIsubcop8hm,astla,rlthm;存储QHIsubsrlthm,a;从acc A中清除QHIrpt#15;QLO=OP7LO/OP8HIsubcop8hm,astla,rltlm;存储QLOldrlthm,T;TQHImpyuop8lm,a;存储QHI*OP8LO于acc Asftla,-1;考虑到符号位对商的影响,所以应该右移一位得到正确 ;的有符号数rpt#15;计算QHI*OP8LO/OP8HIsubcop8hm,a;所得到的结果是修正值,放于acc A中and#0FFFFh,a;将修正值(在低16bit)取出nega;将修正值的负号加上addsrltlm,a;加上 QLOaddrlthm,16,a;加上 QHI在经过上述这段除法运算程序之后,结果就存储在累加器A中,再对之进行归一化,并把数据格式从定点数转换为浮点数存储就完成了的除法计算。3 实验内容本实验需要使用C54X汇编语言实现两个浮点数的加、减、乘、除运算,并通过CCS的存储器窗口观察最后的结果是否正确。实验可以分为以下两步完成:(1) 编写实验程序代码由于本实验是要用C54X的汇编语言实现两个浮点数的四种运算,其中加、减法比较类似故可以用一个程序流程图来表示。加法的主要步骤是转换浮点数为定点数,执行加法时就像前面所讲的那样把尾数移位对齐,再相加,同时还要注意一些特殊情况,比如其中一个数为零,或者是其中一个数比另一个数小许多(即指数相差太大)等等。其程序的主要流程图如下:对于乘法运算,同样需要首先把被乘数和乘数的从浮点数格式分解为符号,指数,尾数三部分,然后再把指数相加,注意是否产生上溢出(=0FFh)或下溢出( bbcop1_gt_op2,BLT;process op1 op2bcop2_gt_op1,BGT;process op2 op1a_eq_bdldop1hm,adaddop2hm,a;add mantissabcres_zero,AEQ;if result is zero process special caseldop1se,b;load exponent in preparation for normalizingtrap2normalizestha,rltsign;Save signed mantissa on stackabsa;Create magnitude value of mantissasftla,6;Prenormalize adjustment of mantissaexpa;Get amount to adjust exp for normalizationnopnorma;Normalize the resultstt,rltexp;Store exp adjustment valueadd#1,b;Increment exp to account for implied carrysubrltexp,b;Adjust exponent to account for normalizationnormalizedstlb,rltexp;Save result exponent on stackbcunderflow,BLEQ;process underflow if occurssub#0ffh,b;adjust to check for overflowbcoverflow,BGEQ;process overflow if occurssftla,-7;Shift right to place mantissa for splittingstla,rltlm;Store low mantissaand#07f00h,8,a;Eliminate implied onestha,rlthm;Save result mantissa on stack;- Conversion of Floating Point Format- Pack -ldrltsign,9,aand#100h,16,a;Get the sign valueaddrltexp,16,a;Add the result exponent togethersftla,7;shift the value to right placedaddrlthm,a;Add the result mantissa togetherreturn_valuetrap 2bfs_startop1_gt_op2absb;if exp OP1 = exp OP2 + 24 then return OP1sub#24,bbcreturn_op1,BGEQadd#23,b;restore exponent difference valuestlb,rltsign;store exponent difference to be used as RPCdldop2hm,a;load OP2 mantissarptrltsign;normalize OP2 to match OP1sftaa,-1bdnormalize;delayed branch to normalize resultldop1se,b;load exponentvalue to prep for normalizationdaddop1hm,a;add OP1 to OP2op2_gt_op1sub#24,b;if exp OP2 = exp OP1 + 24 then return OP1bcreturn_op2,BGEQadd#23,b;Restore exponent difference valuestlb,rltsign;Store exponent difference to be used as RPCdldop1hm,a;Load OP1 mantissarptrltsign;Normalize OP1 to match OP2sftaa,-1bdnormalize;Delayed branch to normalize resultldop2se,b;Load exponent value to prep for normalizationdaddop2hm,a;Add OP2 to OP1op1_zero:return_op2:bdreturn_valuedldop2_hsw,a;Put OP2 as result into Aop2_zero:return_op1:dldop1hm,a;Load signed high mantissa of OP1bcop1_pos,AGT;If mantissa is negative .nega;Negate it to make it a positive valueaddm#100h,op1se;Place the sign value back into op1_seop1_possub#80h,16,a;Eliminate implied one from mantissaldop1se,16,b;Put OP1 back together in acc A as a resultbdreturn_valuesftlb,7addb,aoverflowst#2,errno;load error noldrltsign,16,a;pack sign of resultand#8000,16,aor#0ffffh,a;result low mantissabdreturn_valueadd#07f7fh,16,a;result exponentunderflowst#1,errno;load error nobreturn_valueres_zerobdreturn_valuesuba,anop浮点数减法源程序fs1.asm:.title for test user program . .mmregs.global mainstart.deffs_start.reffm_start,errnoop3va

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论