DSP2833X-C语言+程序烧写_第1页
DSP2833X-C语言+程序烧写_第2页
DSP2833X-C语言+程序烧写_第3页
DSP2833X-C语言+程序烧写_第4页
DSP2833X-C语言+程序烧写_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

DSP原理与应用

TheTechnology&ApplicationsofDSPs北京交通大学电气工程学院夏明超郝瑞祥万庆祝第二章:DSP系统开发第2.1节概述第2.2节DSP汇编语言概述及汇编程序设计第2.3节DSPC语言程序设计第2.4节DSPC与汇编混合编程第2.5节DSP程序烧写习题第2.1节概述汇编语言:开发的效率高,程序执行速度快,而且可以合理利用芯片的硬件资源开发难度较大,开发周期长,可读性和可移植性差。C语言开发:具有兼容性和可移植的优点,有利于缩短开发周期和减少开发难度在运算量较大的情况下,C代码的效率还是无法和手工编写的汇编代码的效率相比,比方FFT运算,C和汇编的混合编程那么可以充分利用前两者的优点,以到达最正确利用DSP资源的目的。C和汇编语言混合编程必须遵循相关函数调用规那么和存放器调用规那么,否那么会带来意想不到的问题。第2.1节概述CCS开发实例演示第二章:DSP系统开发第2.1节概述第2.2节DSP汇编语言概述及汇编程序设计第2.3节DSPC语言程序设计第2.4节DSPC与汇编混合编程第2.5节DSP程序烧写习题第2.2节DSP汇编语言概述及汇编程序设计汇编语言:累加,算术计算和逻辑运算辅助存放器和数据页操作TREG,PREG和乘法指令直接内存访问指令(DMA)和IO操作指令程序空间访问指令跳转指令、存放器操作指令浮点运算指令汇编程序设计:生成可执行代码过程例如文件第累加,算术计算和逻辑运算第累加,算术计算和逻辑运算第累加,算术计算和逻辑运算第累加,算术计算和逻辑运算第辅助存放器和数据页操作第辅助存放器和数据页操作第2.2.3TREG,PREG和乘法指令第2.2.3TREG,PREG和乘法指令第2.2.3TREG,PREG和乘法指令第直接内存访问(DMA)和IO操作指令第程序空间访问指令第2.2.6跳转指令第2.2.7存放器操作指令第2.2.7存放器操作指令第2.2.7存放器操作指令第2.2.8浮点运算指令浮点数简介(IEEE754)单精度浮点数:1位符号位,8位指数,23位有效数IEEE754-IEEEStandard754forBinaryFloatingPointArithmetic单精度浮点数范围:±3.4028235*1038在此范围内也无法精确表述所有浮点数

精度:1.19209290*10-38可精确表述的数必须可以用2的指数幂次组合描述第2.2.8浮点运算指令浮点数简介(IEEE754)单精度浮点数:1位符号位,8位指数,23位有效数IEEE754-IEEEStandard754forBinaryFloatingPointArithmetic例:0011111101100110011001100110011016进制为:0X3F666666整形数为1063675494单精度下:符号位0(+)

指数位E(01111110)2=126,e=-1尾数210

实际值

第2.2.8浮点运算指令浮点数简介(IEEE754)单精度浮点数:1位符号位,8位指数,23位有效数IEEE754-IEEEStandard754forBinaryFloatingPointArithmetic单精度运算精度:加、减、乘、除、平方根、余数、将浮点格式的数舍入为整数值、在不同浮点格式之间转换、在浮点和整数格式之间转换以及比较。四种舍入方向:向最近数方向,向负无穷大,向正无穷大以及向0。五种类型的浮点异常是:无效运算、被零除、上溢、下溢和不精确。*常犯错误:f==0,应该为-e<f<e。第2.2.8浮点运算指令8个浮点结果存放器(RnH)浮点状态存放器(STF)重复块存放器TMS320C28xFloatingPointUnitandInstructionSetReferenceGuide第2.2.8浮点运算指令算术运算ABSF32:32位浮点数绝对值运算ADDF32:32位浮点数加法运算SUBF32:32位浮点数减法运算MPYF32:32位浮点数乘法运算,MACF32:32位浮点数乘加运算EINVF32:32位浮点数倒数运算(1/X)EISQRTF32:32位浮点数开方倒数运算(1/sqrt(x))NEGF32:32位浮点数取反CMPF32,MAXF32,MINF32:32位浮点数比较、最大、最小值第2.2.8浮点运算指令整数浮点数转换F32TOI16,F32TOI16R:32位浮点数转为16位整数F32TOI32:32位浮点数转为32位整数F32TOUI16,F32TOUI16R:32位浮点数转为16位无符号整数F32TOUI32:32位浮点数转为32位无符号数整数I16TOF32:16位整数转为32位浮点数I32TOF32:32位整数转为32位浮点数UI16TOF32:16位无符号整数转为32位浮点数UI32TOF32:32位无符号整数转为32位浮点数第2.2.8浮点运算指令存放器操作MOV16:16位浮点数内存操作MOV32:32位浮点数内存操作MOVD32:32位浮点数内存操作及复制MOVF32:32位浮点数立即数内存操作MOVI32:32位浮点数立即数(16进制)内存操作MOVIZ32.MOVIZF32:浮点存放器高16位操作MOVXI:浮点存放器低16位操作MOVST0:STF内容放至ST0第2.2.8浮点运算指令存放器操作TESTTF:测试STF中标志位SETFLAG:STF中标志位置位SAVEFLAG:保存STF存放器内容ZERO,ZEROA:浮点存放器清零SWAPF:浮点存放器内容交换PUSH:压栈POP:出栈RESTORE:恢复RPTB:重复执行第2.2.9汇编程序设计-生成可执行代码第2.2.9汇编程序设计-例如文件d文件:链接控制文件,用于定义目标的程序,数据,I/O存储映射.MEMEORY{PAGE0:/*ProgramMemory*/ZONE0:origin=0x004000,length=0x001000/*XINTFzone0*/RAML0:origin=0x008000,length=0x001000/*on-chipRAMblockL0*/RAML1:origin=0x009000,length=0x001000/*on-chipRAMblockL1*/RAML2:origin=0x00A000,length=0x001000/*on-chipRAMblockL2*/RAML3:origin=0x00B000,length=0x001000/*on-chipRAMblockL3*/ZONE6A:origin=0x100000,length=0x00FC00/*XINTFzone6-programspace*/ZONE7:origin=0x200000,length=0x100000/*XINTFzone7*/FLASHH:origin=0x300000,length=0x008000/*on-chipFLASH*/……}第2.2.9汇编程序设计-例如文件d文件:链接控制文件,用于定义目标的程序,数据,I/O存储映射.SECTIONS{/*Allocateprogramareas:*/.cinit:>FLASHAPAGE=0.pinit:>FLASHA,PAGE=0.text:>FLASHAPAGE=0codestart:>BEGINPAGE=0ramfuncs:LOAD=FLASHD,RUN=RAML0,LOAD_START(_RamfuncsLoadStart),LOAD_END(_RamfuncsLoadEnd),RUN_START(_RamfuncsRunStart),PAGE=0csmpasswds:>CSM_PWLPAGE=0csm_rsvd:>CSM_RSVDPAGE=0

/*Allocateuninitalizeddatasections:*/.stack:>RAMM1PAGE=1.ebss:>RAML4PAGE=1.esysmem:>RAMM1PAGE=1……}第2.2.9汇编程序设计-例如文件.h文件:标号,地址,中断向量等定义;Filename:280x.hIMR .set0004h;InterruptMaskRegisterIFR .set0006h;InterruptFlagRegister;SystemconfigurationandinterruptregistersSCSR1 .set7018h;SystemControl&Statusregister.1SCSR2 .set7019h;SystemControl&Statusregister.2DINR .set701Ch;DeviceIdentificationNumberregister.PIVR .set701Eh;PeripheralInterruptVectorregister.PIRQR0 .set7010h;PeripheralInterruptRequestregister0PIRQR1 .set7011h;PeripheralInterruptRequestregister1PIRQR2 .set7012h;PeripheralInterruptRequestregister2PIACKR0 .set7014h;PeripheralInterruptAcknowledgeregister0PIACKR1 .set7015h;PeripheralInterruptAcknowledgeregister1PIACKR2 .set7016h;PeripheralInterruptAcknowledgeregister2;Filename:vector.h.sect "vectors"RSVECT BSTART;ResetVectorINT1 BGISR1;InterruptLevel1INT2 BGISR2;InterruptLevel2INT3 BGISR3;InterruptLevel3INT4 BGISR4;InterruptLevel4INT5 BGISR5;InterruptLevel5INT6 BGISR6;InterruptLevel6RESERVEDBPHANTOM;ReservedSW_INT8BPHANTOM;SoftwareInterruptSW_INT9BPHANTOM;SoftwareInterruptSW_INT10BPHANTOM;SoftwareInterruptSW_INT11BPHANTOM;SoftwareInterruptSW_INT12BPHANTOM;SoftwareInterruptSW_INT13BPHANTOM;SoftwareInterruptSW_INT14BPHANTOM;SoftwareInterruptSW_INT15BPHANTOM;SoftwareInterruptSW_INT16BPHANTOM;SoftwareInterruptTRAPBPHANTOM;TrapvectorNMIBNMI;Non–maskableInterruptEMU_TRAPBPHANTOM;EmulatorTrapSW_INT20BPHANTOM;SoftwareInterruptSW_INT21BPHANTOM;SoftwareInterruptSW_INT22BPHANTOM;SoftwareInterruptSW_INT23BPHANTOM;SoftwareInterruptSW_INT24BPHANTOM;SoftwareInterrupt第2.2.9汇编程序设计-例如文件.asm文件:程序文件*FileName:SPI.asm.include280xA.h.includevector.h.bssGPR0,1;Generalpurposeregisters..bssGPR3,1KICK_DOG.macro;Watchdogresetmacro LDP#00E0h SPLK#05555h,WDKEY SPLK#0AAAAh,WDKEY LDP#0h .endm;MAINCODE–startshere.textSTART: LDP#0 SETCINTM SPLK#0h,GPR3 OUTGPR3,WSGR CLRCSXM CLRCOVM CLRCCNF LDP#WDCR>>7 SPLK#006Fh,WDCR KICK_DOG LDP#SCSR1>>7 SPLK#0020h,SCSR1第二章:DSP程序设计第2.1节概述第2.2节DSP汇编语言概述及汇编程序设计第2.3节DSPC语言程序设计第2.4节DSPC与汇编混合编程第2.5节DSP程序烧写习题第2.3节DSPC语言程序设计支持ANSIC:提供相应的编译器和优化工具对ANSIC进行了限定和扩展运行库:字符串操作动态地址分配数据转换…第2.3节DSPC语言程序设计变量和标识:变量和标识符长度100个字符,区分大小写变量和标识符的符号集为ASCII,不支持多字节符号〔如汉字〕。字符或字符串常量中的16进制ESC码(特殊字符,如0X07)可能会有32位的值。多字符的字符变量最后一个有效,如‘abc’是‘c’数据类型:Size_t(sizeof的结果)定义为unsignedintPtrdiff_t(指针加减结果)定义为int所有的整数类型(char,short,int,以及这些类型的无符号型)都是相同类型,并代表16位的二进制值.Long和unsignedlong代表32位二进制值.第2.3节DSPC语言程序设计数据类型:有符号数是用二进制补码表示.数据单元的根底是字(16位),BYTE和WORD一样char是有符号类型,等同于int枚举型(enum)用16位值表示,等同于int浮点类型(float,double)是相同的,遵循TMS320C2x/C2xx/C5x的32位浮点类型.Long和float的数据存储格式为低有效字存储在低地址的方式.Longlong和longdouble是64位的.第2.3节DSPC语言程序设计数据类型:第2.3节DSPC语言程序设计类型转换:浮点数转为整数为取整截断指针类型(pointer)和int可以自由转换farpointer为22位有效位表达式:有符号整数相除,商符号由两个数共同决定,余数符号同被除数10/-3=-3,余1;-10/3=-3余-1有符号数右移为算术右移,符号位不变第2.3节DSPC语言程序设计C访问16位乘法结果的高16位:intm1,m2;intresult;result=((long)m1*(long)m2)>>16;浮点数:32bitsFPU+,-,×,÷比较(>,<,>=,<=,==,!=)同int,long的相互转换以上操作均通过相应的汇编指令(即内部硬件机制)实现。(无FPU时处理浮点运算需要通过浮点数运算库,运算效率低)第2.3节DSPC语言程序设计直接访问存放器通过cregister语句实现: externcregistervolatileunsignedintIFR; IFR=0;第2.3节DSPC语言程序设计预处理:预处理忽略所有不支持的#pragma指令支持如下#pragma:.CODE_ALIGN·CODE_SECTION·DATA_ALIGN·DATA_SECTION·FAST_FUNC_CALL·FUNC_EXT_CALLED·INTERRUPT·MUST_INTERATE·UNROLL预处理必须在函数外,在所有声明之前第2.3节DSPC语言程序设计CODE_ALIGN:为某一段程序指定特定的代码存储边界,以保证某函数代码存于特定位置。#pragmaCODE_ALIGN(func,constant)#pragmaCODE_ALIGN(constant)Constant必须是2的幂次,以保证内存边界问题第2.3节DSPC语言程序设计CODE_SECTION:为某一段程序指定特定的代码存储段,以便单独分配存储空间#pragmaCODE_SECTION(symbol,“section_name”)#pragmaCODE_SECTION(“section_name”)例:#pragmaCODE_SECTION(fn,“my_sect”) intfn(intx) { return0; }汇编结果:.file“CODEN.c”.sect”my_sect”.global_fn.sym_fn,_fn,36,2,0.func3第2.3节DSPC语言程序设计DATA_ALIGN:为某一段数据指定特定的代码存储边界,以保证特定数据存于特定位置。#pragmaDATA_ALIGN(symbol,constant)#pragmaDATA_ALIGN(constant)Constant必须是2的幂次,以保证内存边界问题第2.3节DSPC语言程序设计DATA_SECTION:为某一段数据指定特定的数据存储段,以便单独分配存储空间,例如同.bss内存分开,或单独分配连续的存储空间#pragmaDATA_SECTION(symbol,“section_name”)例:#pragmaDATA_SECTION(bufferB,“BufferB_sect”) charbufferA[512]; charbufferB[512];汇编结果:

.global_bufferA .bss_bufferA,512,4 .global_bufferB_bufferB: .usect“BufferB_sect”,512,4第2.3节DSPC语言程序设计SECTIONS{ VECTORS:{}>PM PAGE0 .TEXT:{}>PM PAGE0 .BSS:{}>BLK_B2 PAGE1 .DATA:{}>BLK_B1 PAGE1BufferB_sect:{}>SARAM_DPAGE1}第2.3节DSPC语言程序设计FAST_FUNC_CALL:指明某一函数调用时采用快速函数调用(FFC)机制,而不是使用普通函数调用流程: FFC进栈出栈及函数返回有所不同,调用更快速。 #pragmaFAST_FUNC_CALL(func)

这类函数返回时的asm代码必须是: LB*XAR7第2.3节DSPC语言程序设计FUNC_EXT_CALLED:指明某一未使用的函数,使其不会在C优化时被删除。 #pragmaFUNC_EXT_CALLED(func)第2.3节DSPC语言程序设计INTERRUPT:指明函数为中断处理函数(函数返回机制使用IRP)#pragmaINTERRUPT(func);#pragmaINTERRUPT;#pragmaINTERRUPT(func,{HPI|LPI});#pragmaINTERRUPT({HPI|LPI});)FPU有高优先级中断(HPI)和低优先级中断(LPI)处理机制,通过此预编译实现。第2.3节DSPC语言程序设计MUST_ITERATE:指明循环必须被执行的次数,以防止循环被优化掉#pragmaMUST_ITERATE(min,max,mult);有时通过空循环建立必须的延时,单在程序优化时会被自动优化掉。例如:For(i=0;i<100;i++){}编译器在优化时会去掉此循环,使用MUST_ITERATE可以保证此循环执行。第2.3节DSPC语言程序设计嵌入汇编代码:asm(“assemblertext”);例如:asm(“clrcintm”);编译器不会进行语法检查,直接生成汇编代码嵌入的汇编指令应不破坏C语言的环境,例如堆栈结构、当前AR等,或不可控的跳转等。带asm语句的代码,使用优化器时须小心,因为优化器可能会改变asm语句附近的代码顺序,而引起不期望的结果.第2.3节DSPC语言程序设计访问IO:先定义io端口号,然后使用ioporttypeporthex_numtype用16位数据表示例: ioportintportd0ff;/*IO端口d0ff*/ portd0ff=a; /*输出a值到portd0ff*/ b=portd0ff; /*读输入portd0ff值到b*/ IN*+FP[7],*(0d0ffH)ioport变量定义必须在文件头位置定义,不能在函数中定义.ioport变量的使用跟普通变量一样。

call(portd0ff); a=portd0ff+b; portd0ff+=a;第2.3节DSPC语言程序设计中断处理:查询式和回调(中断效劳程序)两种方式。查询式: 程序中查询中断标志及相应的存放器,判断中断的发生并进行相应处理。 优点:流程易于控制,不会发生中断嵌套问题,一般不会丧失中断。 缺点:中断实时性差。第2.3节DSPC语言程序设计回调式: 为中断指定回调处理函数(中断效劳程序),由CPU中断处理机制自动调用。 优点:中断实时性好,程序结构简洁,类似于windows的消息驱动机制。 缺点:处理不好容易造成中断嵌套或丧失中断,造成逻辑混乱。第2.3节DSPC语言程序设计中断效劳函数:两种方式定义中断效劳函数。a)c_intd方式定义的函数,c_int00作系统复位函数b)Interrupt关键词定义的函数。例:voidc_int01(){}interruptvoidtimer2_isr(){}第2.3节DSPC语言程序设计中断效劳函数与相应的中断对应: 通过vectors字段对应:*cvectors.asm.ref_c_int00,_timer2_isr.sect”vectors”rset:B_c_int00;00hresetint1:Bint1;02hINT1int2:Bint2;04hINT2int3:B_timer2_isr;06hINT3int4:Bint4;08hINT4第2.3节DSPC语言程序设计cmd文件:MEMORY{PAGE0:/*ProgramMemory*/VECS:org=00000h,len=00040h/*internalFLASH*/……}SECTIONS{ /*SectionsgeneratedbytheC–compiler*/ .text:>FLASHPAGE0/*initialized*/…… /*Sectionsdeclaredbytheuser*/ vectors:>VECSPAGE0/*initialized*/}第2.3节DSPC语言程序设计中断效劳函数: 中断效劳函数类型必须是void。 中断效劳函数要尽量短小,减少中断效劳占用时间,以防止发生中断嵌套或丢中断。 多个中断可以共用一个中断效劳函数,除了int00。 注意IMR、INTM等中断控制量的设置。 中断效劳函数可能和某些编译选项和优化冲突,需注意协调。第2.3节DSPC语言程序设计中断效劳函数: 中断效劳函数可以像其他函数一样访问全局变量、分配局部变量和调用其它函数。 进入中断效劳函数,编译器自动保护与运行上下文相关的存放器,并在中断效劳函数结束时恢复运行环境。但并不保存所有存放器 中断效劳程序可以任意修改不被保护的存放器,如外设控制存放器。 中断效劳函数也可以被其他c程序调用,但效率较差。 c_int00是系统保存的复位中断函数,不会被调用,也不需要保护任何存放器。 中断效劳函数入口地址放在相应的中断向量处。第2.3节DSPC语言程序设计第二章:DSP程序设计第2.1节概述第2.2节DSP汇编语言概述及汇编程序设计第2.3节DSPC语言程序设计第2.4节DSPC与汇编混合编程第2.5节DSP程序烧写习题第2.4节DSPC与汇编混合编程C语言和汇编语言混合编程的四种方法(1)独立编写汇编程序和C程序,分开编译或汇编成各自的目标代码模块,再用链接器将二者链接起来。这种方法比较灵活,但是设计者必须自己维护各汇编模块的入口和出口代码,自己计算传递的参数在堆栈中的偏移量,工作量较大,但是能做到对程序的绝对控制。(2)在C程序中使用汇编程序中定义的变量和常数。(3)在C程序中内嵌汇编语句。这种方法可以实现C语言无法实现的一些硬件控制功能,如修改中断控制存放器。(4)将C语言编译生成相应的汇编代码,手工修改和优化C编译器生成的汇编代码。采用这种方法可以控制C编译器,从而产生具有交叉列表的汇编程序,而设计者可以对其中的汇编语句进行修改,然后对汇编程序进行编译,产生目标文件。后3种方法由于在C中直接嵌入了汇编语言,易造成程序混乱,破坏C环境,甚至导致程序崩溃,而开发者又很难对不良结果进行预期和有效控制。而如果采用第一种方法,只要遵循有关C语言函数调用规那么和存放器规那么,就能预见到程序运行的结果,保证程序正确。第2.4节DSPC与汇编混合编程DSP

C编译器将存储空间分为两个线性空间:程序存储空间,存储可执行码数据存储空间,存储程序执行过程中的数据和堆栈编译器将存储空间以分段(section)的方式分配和管理。用户以不同的方式分配存储器,可以形成不同的系统配置,连接器将各个段连接在一起形成最终完整的存储器结构。*注意:是由连接器决定存储器影射而不是由编译器。第2.4节DSPC与汇编混合编程已初始化的段:.text包含所有可执行代码和浮点型常量PAGE0.pinit包含初始化时的程序代码PAGE0.cinit包含初始化变量和常量表PAGE0.const包含字符串常量,以及以const修饰的全局或静态变量的声明和初始化PAGE1.econst扩展常量PAGE1.switch包含switch语句的分支跳转地址表PAGE0第2.4节DSPC与汇编混合编程未初始化的段:.bss为全局和静态变量保留空间PAGE1.ebss扩展变量空间PAGE1.stack为系统软件堆栈分配空间PAGE1.sysmem为动态分配的内存保留空间,可以被calloc、malloc、realloc函数使用PAGE1.esysmem扩展动态内存空间PAGE1汇编自动生成.text,.bss和.data段。C编译器不使用.data段。第2.4节DSPC与汇编混合编程用户定义的段:用户使用CODE_SECTION,DATA_SECTION定义的段,如上面的my_sect,BufferB_sect第2.4节DSPC与汇编混合编程/**********************************//Linkercommandfilelinkd/**********************************/-c/*ROMautoinitializationmodel*/-mexample.map/*Createamapfile*/-oexample.out/*Outputfilename*/main.obj/*FirstCmodule*/sub.obj/*SecondCmodule*/asm.obj/*Assemblylanguagemodule*/−lrts25.lib/*Runtime−supportlibrary*/−lmatrix.lib/*Objectlibrary*/MEMORY{PAGE0:PROG:origin=30h,length=0EFD0hPAGE1:DATA:origin=800hlength−0E800h}SECTIONS{.text>PROGPAGE0.cinit>PROGPAGE0.switch>PROGPAGE0.bss>DATAPAGE1.const>DATAPAGE1.sysmem>DATAPAGE1.stack>DATAPAGE1}第2.4节DSPC与汇编混合编程系统堆栈: DSP硬堆栈:8级,用于保存函数调用、中断效劳函数等的返回地址,也可以用PUSH等保存其他变量 C编译器可以生成一定大小的软堆栈:分配局部变量传递函数参数保存处理器状态保存函数返回地址保存临时结果保存存放器内容第2.4节DSPC与汇编混合编程系统堆栈:编译器利用两个辅助存放器来管理堆栈:SP堆栈指针(StackPointer),指向当前堆栈顶。XAR2帧指针(FP,FramePointer),指向当前帧的起始点,每个函数都会在堆栈顶部建立一个新的帧,用来保存局部或临时变量。C语言环境自动操作这两个存放器。如果编写用到堆栈的汇编语言程序,一定要注意正确使用这两个存放器。默认堆栈大小是1k。用-stack连接选项可以指定软件堆栈的大小,用C编写DSP程序一定注意保存足够的堆栈空间!注意:编译器不会检查堆栈溢出情况,堆栈溢出会破坏DSP 运行环境,导致程序失败。编写DSP程序和配置DSP 存储器资源要注意防止堆栈溢出的发生。第2.4节DSPC与汇编混合编程动态内存分配:TMS320C2x/C2xx/C5xC语言可调用malloc、calloc或realloc函数动态申请内存,申请的内存将分配在.sysmem块。动态分配的内存只能通过指针进行访问,动态分配使用后可以释放,这样可以用于其它目的。将大数组通过这种方式来分配可以节省.bss块的空间。通过连接器的-heap选项可以定义.sysmem块。unsignedintdata[100];unsignedint*data;data=(unsignedint*)malloc(100*sizeof(unsignedint));第2.4节DSPC与汇编混合编程存放器使用规那么: TMS320C2x/C2xx/C5x运行环境对存放器的使用有严格的要求,编写涉及到存放器的汇编程序,必须严格遵守这些规那么,否那么可能造成系统工作异常。存放器规那么规定了编译器如何使用存放器,和存放器在函数调用的过程中如何进行保护。存放器按照保护方式分为两种: 调用保存〔saveoncall〕,调用其它函数的函数负责保存这些存放器的内容。 入口保存〔saveonentry〕,被调用的函数负责保存这些存放器的内容。注:无论是否使用优化编译,都必须遵守这些存放器规那么。第2.4节DSPC与汇编混合编程存放器使用规那么:第2.4节DSPC与汇编混合编程存放器使用规那么:第2.4节DSPC与汇编混合编程状态存放器使用:单元名称假定值修改ARP辅助寄存器指针1YesC进位标志-YesDP数据页-YesOV溢出标志-YesOVM溢出模式0NoPM乘积移位模式0NoSXM符号扩展模式-YesTC测试模式-Yes第2.4节DSPC与汇编混合编程函数调用规那么:TMS320C2x/C2xx/C5x运行环境对函数调用有严格的要求,要调用C函数或要被C程序调用的汇编语言程序必须遵守这些规那么,否那么可能破坏C运行环境,造成程序失败。当进行函数调用时,调用者要将传递参数压入系统堆栈传给被调用的函数,并将函数返回地址压栈。被调用的函数要在函数运行结束时将返回值放在累加器里返回给调用者函数。函数参数及返回地址等都是通过堆栈传递的,要编写汇编函数,必须明确函数调用的过程中堆栈的变化和应该进行的处理函数调用过程中堆栈情况:第2.4节DSPC与汇编混合编程C语言调用函数时的工作:将参数反向压入堆栈〔最右端的参数最先压栈,最左端的参数最后压栈〕,这样,当函数被调用时,最左端的参数会在堆栈的最顶部。使用被调用函数。被调用函数返回前处理各存放器。当被调用函数运行结束时,调用者函数要将压入堆栈的参数弹出以恢复堆栈状态。注:如果用C程序调用汇编语言程序,C编译器会自动产生代码完成这些工作。第2.4节DSPC与汇编混合编程C语言函数被调用时的工作:将返回地址从硬件堆栈弹出,压入软件堆栈。将FP(SP)压入软件堆栈。分配局部帧(Frame)。如果函数中要修改AR6、AR7,将它们压入堆栈,其它存放器不用进行保护就可以进行修改。实现函数功能。如果函数返回标量数据,将它放入累加器。如果保护了AR6、AR7,恢复这两个存放器。删除局部帧。恢复FP(SP)。将返回地址从软件堆栈中弹出,压入硬件堆栈。返回。第2.4节DSPC与汇编混合编程POPD*+ ;返回地址从硬堆栈中弹出,压入软堆栈(由AR1指示)SARAR0,*+ ;AR0(FP)入软堆栈SARAR1,* ;AR1(SP)入软堆栈LARKAR0,SIZE ;FP=局部帧大小LARAR0,*0+ ;FP=SP,SP+=SIZE:分配局部帧SARAR6,*+ ;保存AR6SARAR7,*+ ;保存AR7... ;函数功能局部MAR*,AR1 ;设置当前AR为AR1MAR*- ;LARAR7,*- ;恢复AR7LARAR6,*- ;恢复AR6SBRKSIZE+1 ;释放局部帧(恢复AR1(SP)LARAR0,*- ;恢复AR0(FP)PSHD* ;返回地址压入硬堆栈RET ;返回第2.4节DSPC与汇编混合编程一些特殊的情况:返回一个结构:当函数的返回值为一个结构时,调用者负责分配存储空间,并将存储空间地址作为最后一个输入参数传递给被调用函数。被调用函数将要返回的结构拷贝到这个参数所指向的内存空间。不将返回地址移动到软件堆栈:当被调用函数不再调用其它函数,或者确定调用深度不会超过8级,可以不用将返回地址移动到软件堆栈。不分配局部帧:如果函数没有输入参数,不使用局部变量,就不需要修改XAR2〔FP〕,因此也不需要对其进行保护。第2.4节DSPC与汇编混合编程C与汇编混合:C程序调用汇编函数必须要满足前面介绍的调用规那么和存放器规那么,C程序可以访问汇编语言定义的变量或调用汇编语言函数,同样汇编语言也可以访问C程序定义的变量或调用C函数。用C程序调用汇编函数有以下本卷须知:所有的函数〔不管用C编写还是用汇编语言编写〕都必须满足前面介绍的存放器规那么。对于一些存放器,如果函数要修改其内容,那么必须事先对其进行保护。这些存放器包括:XAR2(FP),SP,AR6,AR7。其它的存放器可以不用保护自由使用。第2.4节DSPC与汇编混合编程本卷须知:如果函数改变了状态存放器某些有假定值的位,那么必须在函数结束前恢复其原有值。尤其要注意ARP必须为AR1。中断效劳程序必须保护所有其用到的存放器。long型和float型变量在存储器中的存储方式为低有效位在低端地址。函数返回值要通过累加器进行传递。编译器会在所有对象的名称前面加下横线“_”,因此汇编语言模块定义对象名称时也要以下横线为前缀,才能使定义的对象可以被C代码访问。例如C语言对象x在汇编语言中就是_x。汇编语言可以使用任何不带下横线前缀的变量而不会和C语言对象冲突。任何汇编语言定义的对象,如果要被C程序访问,那么必须用.global修饰。同样任何C语言定义的对象,如果要被汇编语言访问,也必须以.global修饰。C和汇编互相调用函数时,需保证参数压栈和出栈的一致性。第2.4节DSPC与汇编混合编程第2.4节DSPC与汇编混合编程C中访问汇编变量:通常有两种方式。1.访问.bss块中的变量:将要访问的变量定义在.bss块中。用.golbal修饰要访问的

温馨提示

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

评论

0/150

提交评论