第六章DSP的寻址方式和汇编指令当硬件执行指令时,寻找指令所指定的参与运算飞操作数的方式——寻址方式。根据程序的要求采用不同的寻址方式,可以有效地缩短程序的运行时间和提高代码执行效率。汇编指令是可执行指令,每一条指令对应一条机器码,用来控制处理器仲的执行部分进行各种操作。在本章节当中将主要以基于C28x的DSP芯片为例,为读者讲解DSP的寻址方式和汇编指令系统,其中大部分内容也可适用于其他Ti公司的DSP产品。6.1汇编语言指令集概述在学习C28x系列DSP的寻址方式和汇编指令指令之前,先来对一些基础的知识进行讲解一下先,在汇编程序当中开发人员会常常使用到许多的特殊符号和标志,它们都具有特殊的含义,在学习汇编之前读者们必须先理解这些符号和标志含义,在这里会对其中最常用最重要的操作数符号和寄存器经行详细说明。在进行汇编讲解之前先来了解一下开发的核心——CPU。在TMS320C2000系列中,CPU内核为:C20x/C24x/C240x:C2xLP:C27x/C28x:C27x、C28x这些CPU的硬件结构有一定差别,指令集也不相同,但是,在C28x芯片中可以通过选择兼容特性模式,使C28xCPU与C27xCPU及C2xLPCPU具有最佳兼容性。可通过状寄存器STl的位OBJMODE和位AMODE的组合,选定模式。C28x芯片具有3种操作模式:1.C28x模式:在该模式中,用户可以使用C28x的所有有效特性、寻址方式和指令系统,因此,一般应使C28x芯片工作于该种模式。2.C27x目标——兼容模式:在复位时,C28x的CPU处于C27x目标-兼容模式。在该模式下,目标码与C27xCPU完全兼容,且它的循环—计数也与C27xCPU兼容。3.C2xLP源——兼容模式:该模式允许用户运行C2xLP的源代码,这些源代码是用C28x代码生成工具编译生成的。在下面的讲解当中会牵涉到模式的转换,希望读者要搞清楚每一个模式的对应关系。本节假设条件为芯片工作于C28x模式(OBJMODE=1,AMODE=0)。复位后,通过执行指令C28OBJ或者SETCOBJMODE将ST1中的OBJMODE位置1,芯片即可工作于C28x模式。6.1.1DSP中的操作数汇编语言离不开操作符和操作数,操作符可以认为就是CPU的指令或者编译器上的伪指令,操作数是指令执行过程中的参与者,也可以说操作数就是指令所控制的对象。如表6-1,表6-2和表6-3对指令中常用到的一些操作数符号进行说明符号描述XARn32位辅助寄存器XAR0~XAR7ARn,ARm32位辅助寄存器XAR0~XAR7的低16位ARnH32位辅助寄存器XAR0~XAR7的高16位ARPn32位辅助寄存器指针,ARP0指向XAR0,ARP1指向XAR1……AR(ARP)ARP指向的辅助寄存器的低16位XAR(ARP)ARP指向的辅助寄存器AX累加器的高16位寄存器AH或者16位寄存器AL#立即数助记符PM乘积移位方式(+4,1,0,-1,-2,-3,-4,-5,-6)PC22位程序计数器~按位求反码[loc16]Loc16寻址方式对应的16位数据0:[loc16]将Loc16寻址方式对应的16位数据进行零扩展S:[loc16]将Loc16寻址方式对应的16位数据进行符号扩展[loc32]Loc32寻址方式对应的32位数据0:[loc32]将Loc32寻址方式对应的32位数据进行零扩展S:[loc32]将Loc32寻址方式对应的32位数据进行符号扩展7bit表示7位立即数0:7bit7位立即数,零扩展S:7bit7位立即数,符号扩展8bit表示8位立即数0:8bit8位立即数,零扩展S:8bit8位立即数,符号扩展10bit表示10位立即数0:10bit10位立即数,零扩展S:10bit10位立即数,符号扩展16bit表示16位立即数0:16bit16位立即数,零扩展S:16bit16位立即数,符号扩展22bit表示22位立即数0:22bit22位立即数,零扩展S:22bit22位立即数,符号扩展LSb最低有效位LSB最低有效字节LSW最低有效字MSb最高有效位MSB最高有效字节MSW最高有效字OBJ对于某条指令,位OBJMODE的状态N重复次数(N=0,1,2,3,4,5,6…){}可选字段=赋值==等于表6-1操作数符号及说明在应用程序的开发过程当中少不了的就是算术运算还有比较运算,当然在汇编语言编程的时候也是一样的,在汇编语言当中进行算术运算的操作并不像C/C++那样直观、方便,需要掌握众多的助记符才行,接下来会通过表6-2来说明一下关于算术方面的助记符以及与其相关的标志位。COND语法描述测试标志位0000NEQ不等于Z=00001EQ等于Z-10010GT大于(有符号减法)Z=0且N=10011GEQ大于或等于(有符号减法)N=00100LT小于(有符号减法)N=10101LEQ小于或等于(有符号减法)Z=1或N=10110HI高于(无符号减法)C=1且Z=00111HIS,C高于或相同(无符号减法)C=11000LO,NC低于(无符号减法)C=01001LOS低于或相同(无符号减法)C=1或Z=01010NOV无溢出V=01011OV溢出V=11100NTC测试位为0TC=01101TC测试位为1TC=11110NBIOBIO输入等于零BIO=01111UNC无条件表6-2影响指令的判断条件的说明在汇编程序当中实现乘法操作时一件非常不简单的事,由于是属于纯寄存器操作,因此,开发人员需要准备保存乘法结果的地址,在表6-1当中讲解操作数符号的时候有一个关于乘积操作的符号—PM,那么它的结果保存是如何执行的呢?下面通过表6-3来说明一下。PM保存方式+4P(31:4)=相乘结果中低38位的(27:0),P(3:0)+0+1P(31:1)=相乘结果中低38位的(30:0),P(31)+00P(31:0)=相乘结果中低38位的(31:0)-1P(31:0)=相乘结果中低38位的(32:1)-2P(31:0)=相乘结果中低38位的(33:2)-3P(31:0)=相乘结果中低38位的(34:3)-4P(31:0)=相乘结果中低38位的(35:4)-5P(31:0)=相乘结果中低38位的(36:5)-6P(31:0)=相乘结果中低38位的(37:6)表6-3PM与结果保存方式的关系6.1.2汇编语法指令描述前一小节提到过,汇编指令一般都由操作符和操作数组成,操作符也被称为指令助记符,它是指令中的关键字,表示本条指令操作类型,不能省略。操作数可以省略,也可以有很多,但各操作数之间要用“,”分开。指令助记符与操作数之间要用空格分开。ARn:n为数值0~7,ARn指定下次的辅助寄存器。ind:选择一下7种符号之一:*,*+,*-,*0+,*0-,*BR0+,*BR0-(兼容模式使用)。#:立即寻址方式中常用的前缀。数值前面带“#”,表示该数值为一个立即数。左移。右移。@:当使用C28x语法时,64位字段数据与通过“@”符号来表示,一帮组程序员理解当前正在使用哪种寻址模式。@@:当使用C28x语法时,128位字段数据页通过“@@”符号来表示。loc16:16位寻址方式指定地址单元的内容。loc32:32位寻址方式指定地址单元的内容。#16bitsigned:16位有符号立即数。6.2寻址方式通过6.1节当中读者们应当对汇编语言编程有了一定的了解,仅仅了解了汇编语言的操作符还是不过的,接下来就从汇编语言最根本的开始学习——寻址方式寻址方式就是寻找操作数或者操作数地址的方式,在存储器中,操作数或指令字写入或读出的方式,有地址指定方式、相联存储方式或堆栈存取方式。几乎所有的计算机,在内存中都采用地址指定方式。当采用地址指定方式时,形成操作数或指令地址的方式称为寻址方式。C28x系列DSP的指令集采用7种寻址方式:1.直接寻址方式:DP(数据页指针),在此方式中,16位的DP寄存器被当做一个固定的页指针,讲指令中提供6未或者7位的地址偏移量与DP寄存器中的值组合起来就构成完整的地址。当访问具有固定地址的数据结构时,这种寻址方式特别有用,例如,外设寄存器和C/C++中的全局及静态变量。2.堆栈寻址方式:SP(堆栈指针),在这种方式下,16位的SP指针被用来访问软件堆栈的内容。C28x系列的堆栈是从低端地址想高端地址生长的,SP总是指向下一个空的存储单元。当需要访问堆栈中的数据时,SP的值减去指令仲提供的6位偏移量作为被访问数据的地址和,而堆栈指针将在入栈后加1,出栈前减1.3.间接寻址方式:XAR0到XAR7(辅助寄存器指针),在该方式下,32位的XARn寄存器被当做一般的数据指针来使用个。通过相应的指令可以实现操作后XARn加1、操作前/后减1,还可以配合3位偏移量或者其他16位寄存器实现变址寻址。4.寄存器寻址方式:这种方式下,另一个寄存器可以是该次访问的资源或者目的操作数。这样在C28x中既能实现寄存器到寄存器的操作。5.数据/程序/IO空间寻址方式:在这种方式下,存储器中操作数的地址被包含在指令中。6.程序空间间接寻址方式:某些指令可以通过指针来访问位于程序空间中的存储器操作数。由于在C28xCPU中存储器是统一寻址的,所以单周期内可以读取两个操作数。7.字节寻址方式:该方式能访问到股东地址单元的最低有效位和最高有效位。提示:对于基于C28x的DSP芯片来说,以上的7种寻址方式仲出了IO空间寻址方式外其他的都支持。C28x的大多数指令都是利用操作符中的8位字段来选择寻址方式和对寻址方式进行修改.在C28x的指令系统中,这个8位字段用于以下寻址方式:1.loc16:为16位数据访问选择直接/堆栈/间接/寄存器寻址方式。[loc16]表示loc16这种寻址方式对应的16位数据。2.loc32:为32位数据访问选择直接/堆栈/间接/寄存器寻址方式。[loc32]表示loc32这种寻址方式对应的32位数据。在直接寻址方式下,loc16/loc32指的是一个用标号表示的地址,这个地址由16位的DP寄存器和操作码内8位字段的6位或7位偏移量共同决定。[loc16]/[loc32]表示这个地址对应的16/32位数据。以上7种寻址方式都与“loc16/loc32”组合起来使用。在间接寻址方式下,loc16/loc32表示放在辅助寄存器(XAR0~XAR7)中的一个地址,[loc16]/[loc32]表示这个地址对应的16/32位数据。在堆栈寻址方式下,loc16/loc32表示堆栈指针指向的一个堆栈单元,[loc16]/[loc32]表示这个单元内的16/32位数据。在寄存寻址方式下,loc16/loc32表示一个16位或32位寄存器(如ACC、P、XT、AH等),[loc16]/[loc32]表示这些寄存器内的16/32位数据。由于C28x提供了多种寻址方式,因此用寻址方式选择位(AMODE)来选择8位字段(loc16/loc32)的解码。该位属于状态寄存器ST1。寻址方式可以大致归类如下:(1)AMODE=0——该方式是复位后的默认方式,也是C28x的C/C++编译器使用的方式。这种方式与C2xLPCPU的寻址方式不完全兼容。数据页指针偏移量是6位(在C2xLPCPU中是7位),并且不支持所有的间接寻址方式。(2)AMODE=1——该方式包括的寻址方式完全与C2xLP器件的寻址方式兼容。数据页指针的偏移量是7位并支持所有C2xLP支持的间接寻址方式。编译器总是假定AMODE=0,所以它只使用对AMODE=0有效的寻址模式。而汇编器可以通过设置命令行选项实现默认AMODE=0或者AMODE=1。v28:假定AMODE=0(C28x寻址方式)v28–m20:假定AMODE=1(与C2xLP全兼容的寻址方式)在文件中使用内嵌伪指令:.c28_amode:告诉汇编器后面的代码段都假定AMODE=0(C28x寻址方式).lp_amode:告诉汇编器后面的代码段都假定AMODE=1(与C2xLP全兼容的寻址方式)指令操