nullnull 第5章 TMS320C54x汇编语言程序设计内容提要
汇编语言程序设计是应用软件设计的基础,主要任务是利用汇编指令和伪指令编写源程序以完成指定的功能。
本章将结合例子介绍TMS320C54x汇编语言源程序设计的基本
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
,涉及的内容包括:
汇编语言源程序的格式
常数、字符串、符号和
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
达式的规定
堆栈的使用方法
分支、调用、返回控制程序
加法、乘法、除法、长字和并行运算程序
单指令、块重复、循环嵌套等重复操作程序
数据块传送程序
小数运算程序和浮点运算程序 null第5章 TMS320C54x汇编语言程序设计 5.1 概述
5.2 堆栈的使用方法
5.3 控制程序
5.4 算术运算程序
5.5 重复操作程序
5.6 数据块传送程序
5.7 小数运算程序
5.8 浮点运算程序null第5章 TMS320C54x汇编语言程序设计5.1 概述 TMS320C54x汇编语言源程序由源语句组成。这些语句可以包含汇编语言指令、汇编伪指令和注释。程序的编写必须符合一定的格式,以便汇编器将源文件转换成机器语言的目标文件。
本节将介绍汇编语言源程序的格式、各种常数、符号、字符串和表达式的规定。 null第5章 TMS320C54x汇编语言程序设计5.1 概述 汇编语言程序以.asm为扩展名,可以用任意的编辑器编写源文件。一条语句占源程序的一行,长度可以是源文件编辑器格式允许的长度,但汇编器每行最多读200个字符。因此,语句的执行部分必须限制在200个字符以内。 5.1.1 汇编语言源程序格式 null第5章 TMS320C54x汇编语言程序设计1. 源文件格式 5.1.1 汇编语言源程序格式 助记符指令源语句的每一行通常包含4个部分:标号区、助记符区、操作数区和注释区。 [标号][:] 助记符 [操作数] [; 注释]助记符指令语法格式: 【例5.1.1】 助记符指令源语句举例。
NANHUA .set 1 ; 符号NANHUA=1
Begin: LD #NANHUA,AR1 ; 将1加载到AR1 标 号 助记符 操作数 注 释 null第5章 TMS320C54x汇编语言程序设计1. 源文件格式 语句的书写规则: ① 所有语句必须以标号、空格、星号或分号(*或;)开始;
② 标号是可选项,若使用标号,则标号必须从第一列开始;
③ 所有包含有汇编伪指令的语句必须在一行完成指定;
④ 各部分之间必须用空格分开,Tab字符与空格等效;null第5章 TMS320C54x汇编语言程序设计1. 源文件格式 语句的书写规则: ⑤ 程序中注释是可选项。如果注释在第一列开始时,前面必须标上星号或分号,在其他列开始的注释前面必须以分号开头;
⑥ 如果源程序很长,需要书写若干行,可以在前一行用反斜杠字符(\)结束,余下部分接着在下一行继续书写。 null第5章 TMS320C54x汇编语言程序设计2.标号 所有汇编指令和大多数汇编伪指令都可以选用标号,供本程序或其它程序调用。① 标号必须从语句的第1列写起,其后的冒号“:”可任选;
② 标号为任选项,若不使用标号,则语句的第一列必须是空格、星号或分号;
③ 标号是由字母、数字以及下划线和美元符号等组成,最多可达32个字符;
④ 标号分大小写,且第一个字符不能是数字。null第5章 TMS320C54x汇编语言程序设计2.标号 在使用标号时,标号的值是段程序计数器SPC的当前值。
例如,若使用.word伪指令初始化几个字,则标号将指到第一个字。 【例5.1.2】 标号格式举例。
… …
9 000000
10 000040 000A Start: .word 0Ah,3,7
000041 0003
000042 0007;假设汇编了某个其他代码 标号,值为40hnull第5章 TMS320C54x汇编语言程序设计3.助记符 助记符用来表示指令所完成的操作,可以是汇编语言指令、汇编伪指令、宏伪指令。助记符指令:一般用大写,不能从第一列开始 ; 汇编伪指令:用来为程序提供数据和控制汇编进程。以句号“.”开始,且用小写;宏伪指令:用来定义一段程序,以便宏调用来调用这段程序。以句号“.”开始,且用小写; 宏调用:用来调用由宏伪指令定义的程序段。null第5章 TMS320C54x汇编语言程序设计4.操作数 操作数是指指令中参与操作的数值或汇编伪指令定义的内容,紧跟在助记符的后面,由一个或多个空格分开。 操作数之间必须用逗号“,”分隔;
操作数可以是常数、符号或表达式;
操作数中的常数、符号或表达式可用来作为地址、立即数或间接地址;null第5章 TMS320C54x汇编语言程序设计4.操作数(1) 指令的操作数前缀 使用“#”符号作为操作数的前缀;
使用“*”符号作为操作数的前缀;
使用“@” 符号作为操作数的前缀。 汇编器允许指定的常数、符号或表达式作为地址、立即数或间接地址。
作为操作数的前缀有三种情况:null第5章 TMS320C54x汇编语言程序设计(1) 指令的操作数前缀① 用“#” 作前缀 例如:
Label: ADD # 99, B 使用“#”号作为前缀,汇编器将操作数作为立即数处理。即使操作数是寄存器或地址,也将作为立即数。
如果操作数是地址,汇编器将把地址处理为一个数值,而不使用地址的内容。 操作数# 99是一个立即数。 null第5章 TMS320C54x汇编语言程序设计(1) 指令的操作数前缀② 用“*”作前缀 例如:
Label: LD * AR3, B 使用“*”符号作为前缀,汇编器将操作数作为间接地址,即把操作数的内容作为地址。 操作数*AR3指定一个间接地址。该指令将引导汇编器找到寄存器AR3的内容作为地址,然后将该地址中的内容装入指定的累加器B中。 null第5章 TMS320C54x汇编语言程序设计(1) 指令的操作数前缀③ 用“@”作前缀 例如:
Label: LD @ x, A 使用“@”符号作为前缀,汇编器将操作数作为直接地址,即操作数由直接地址码赋值。 只要DP=0,将直接地址x中的内容装入指定的累加器A中。 null第5章 TMS320C54x汇编语言程序设计4.操作数(2) 伪指令的立即数 例如:
SUB # 18, B ; 操作数#18为立即数 将“#”加在数值之前而构成的立即数方式,主要用在指令中。 通常,立即数在伪指令中用的较少,但在某些情况下,立即数也可以作为伪指令的操作数。 例如:
.byte 18 立即数方式没有使用,但汇编器认为操作数是一个数值18(即立即数),用18数值初始化一个字节。null第5章 TMS320C54x汇编语言程序设计5.注释 用来说明指令功能的文字,便于用户阅读。 注释可位于句首或句尾,位于句首时,以“*”或“;”开始,位于句尾时,以分号“;”开始。 注释可单独一行或数行;
注释是任选项。 11 00000 .bss sym, ; 保留空间于.bss
**************************************
* 改变段,允许第五个‘mylab’定义 *
************************************** 例如:null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 汇编器可支持7种类型的常数(常量)。 null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 二进制整型常量最多由16位二进制数字(0或1)组成,后缀为B(或b)。如果数字小于16位,汇编器将其右边对齐,并在前面补零。 1.二进制整数 例如:
10001000B 136(十进制)或88(十六进制)
0111100b 60(十进制)或3C(十六进制)
10b 2(十进制)或2(十六进制)
10001111B 143(十进制)或8F(十六进制) null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 八进制整型常量最多由6位的八进制数字(0到7) 组成,后缀为Q(或q)或前缀为0(零)。 2.八进制整数 例如:
100011Q 32777(十进制)或8009(十六进制)
124q 84 (十进制)或54(十六进制) 八进制常数也可使用C语言的记号,即加前缀0。
0100011 32777(十进制)或8009(十六进制)
0124 84 (十进制)或54(十六进制) null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 十进制整型常量由十进制数字串组成,无后缀。取值范围为:-32 768~32 767或0~65 535。 3.十进制整数 例如:
2118 2118(十进制)或846(十六进制)
65535 65535(十进制)或0FFFF(十六进制)
-32768 -32768(十进制)或8000(十六进制) null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 十六进制整型常量最多由4位十六进制数字组成,带后缀H(或h)。它必须以数字(0~9)开始,也可以加前缀0x。4.十六进制整数 例如:
0DH 14(十进制)或000D(十六进制)
12BCH 4796(十进制)或12BC(十六进制) 十六进制常数也可用C语言记号,即加前缀0x。
0x0D 14(十进制)或000D(十六进制)
0x12BC 4796(十进制)或12BC(十六进制) null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 浮点整型常量由一串十进制数字组成,可以带小数点、分数和指数部分。 5.浮点数 浮点数的表示方法:
[±][n].[n] [E | e] [±] [n] n——为一串十进制数,浮点数前可带加减号(+或-),且小数点必须指定。 例如: 99.e9——有效的数;99e9——非法。
合法:.314 ,3.14 , -.314e-19 。 null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 在程序中使用.set伪指令给一个符号赋值,该符号就成为一个汇编时间常数,等效于一个常数。
为了使用表达式中的常数,赋给符号的必须是绝对值。 6. 汇编时间常数 例如:将常数值18赋给符号bei_hua。
bei_hua .set 18
LD # bei_hua,Anull第5章 TMS320C54x汇编语言程序设计6. 汇编时间常数 例如:
AuxRl .set ARl
MVMM AuxRl,SP 也可以用.set伪指令将符号常数赋给寄存器名。此时,该符号变成了寄存器的替代名。 注意:常量不能进行符号扩展。
如:0ACH等于十六进制的00AC或十进制172,
不等于-84。 null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 字符常数是包括在单引号内的字符串。若单引号之间没有字符,则值为0。每个字符在内部表示为8位ASCII码。 7.字符常数 例如:
‘a’ 内部表示为61 h
‘B’ 内部表示为42 h null第5章 TMS320C54x汇编语言程序设计5.1.2 汇编语言中的常数与字符串 字符串是由双引号括起来的一串字符,最大长度是可以变化的,由要求字符串的伪指令来设置。字符在内部用8位ASCII码来表示。 8.字符串 例如:
“example”
定义了一个长度为7的字符串:example null第5章 TMS320C54x汇编语言程序设计 字符串可用于下列伪指令中:
.copy——作为复制伪指令中的文件名
.sect——作为命名段伪指令中的段名
.setsect——作为该伪指令中的段地址
.byte——作为数据初始化伪指令中的变量名
.string——作为该伪指令的操作数 8.字符串 注意:字符常数与字符串的差别。
字符常数代表单个整数值。
字符串只是一串字符。 null第5章 TMS320C54x汇编语言程序设计5.1.3 汇编源程序中的符号 汇编程序中的符号用于标号、常数和替代字符。 由字母、数字以及下划线和美元符号(A~Z,a~z,0~9,_和$)等组成;
符号名最多可长达200个字符;
在符号中,第1位不能是数字,并且符号中不能含空格。 null第5章 TMS320C54x汇编语言程序设计5.1.3 汇编源程序中的符号 1. 标号 作为标号的符号代表在程序中对应位置的符号地址。
通常,标号是局部变量,在一个文件中局部使用的标号必须是唯一的。
助记符操作码和汇编伪指令名(不带前缀“.”)为有效标号。
标号分大小写。 例如:ABC,Abc,abc是3个不同的符号。 在调用汇编器时使用-c选项,可以不分大小写。 null第5章 TMS320C54x汇编语言程序设计1. 标号 标号还可以作为.global,.ref,.def或.bss等汇编伪指令的操作数。 如:
.global label
lable1 NOP
ADD label,B
B label1null第5章 TMS320C54x汇编语言程序设计2. 符号常数 符号也可被设置成常数值。为了提高程序的可读性,可以用有意义的名称来代表一些重要的常数值。
伪指令.set和.struct/.tag/.endstruct可以用来将常数赋给符号名。
注意:符号常数不能被重新定义。 5.1.3 汇编源程序中的符号 null第5章 TMS320C54x汇编语言程序设计2. 符号常数 【例5.1.3】 定义符号常数举例。 N .set 512
buffer .set 4 * N
nzg1 .set 1
nzg2 .set 2
nzg3 .set 3
item .struct
.int nzg1
.int nzg2
.int nzg3
tang .endstruct
array .tag item
.bss array,tang* N;定义常数
;item结构定义
;常数偏移nzg1 = 1
;常数偏移nzg2 = 2
;常数偏移nzg2 = 3
;声明数组 null第5章 TMS320C54x汇编语言程序设计3. 定义符号常数 使用-d选项可以将常数值与一个符号等同起来。
定义符号常数后,在汇编源文件中可用符号代替和它等同的值。 5.1.3 汇编源程序中的符号 定义格式: asm500 -d name = [value] 汇编命令 汇编选项 符号名称 符号的值 若value省略,则符号的值设置为l。 null第5章 TMS320C54x汇编语言程序设计3. 定义符号常数 注意:内部函数$isdefed中的变量必须括在双引号内。
引号表明变量按字面解释而不是作为替代字符。 null第5章 TMS320C54x汇编语言程序设计4.预先定义的符号常数 汇编器有若干预先定义符号,包括: 5.1.3 汇编源程序中的符号 ① 美元符号$,代表段程序指针SPC的当前值;
② 映像寄存器符号,包括AR0~AR7;
③ 映像寄存器由汇编器设置为符号。用于指定存储器模式。由-mk选项设置,默认值为0 。 null第5章 TMS320C54x汇编语言程序设计5. 替代符号 可将字符串值(变量)赋给符号,使符号名与该变量等效,成为字符串的别名,这种用来代表变量的符号称为替代符号。 5.1.3 汇编源程序中的符号 当汇编器遇到替代符号时,将用字符串值替代符号。和符号常数不同,替代符号可以被重新定义。可在程序中的任何地方将变量赋给替代符号。 例如:
.asg "high",AR2 ;寄存器AR2 null第5章 TMS320C54x汇编语言程序设计5. 局部标号 局部标号是一种特殊的标号,使用的范围和影响是临时性的。 5.1.3 汇编源程序中的符号 定义方法: 注意:局部标号不能用伪指令来定义。 ① 用$n来定义。n是0~9的十进制数;
② 用NAME?定义。NAME是任何一个合法的符号名。汇编器用紧随其后一个唯一数值的句点代替问号。 null第5章 TMS320C54x汇编语言程序设计5. 局部标号 局部标号可以被取消定义,并可以再次被定义或自动产生。 取消局部变量的方法: ① 使用.newblock伪指令;
② 使用伪指令.sect,.text或.data改变段 ;
③ 使用伪指令.include或.copy,进入include文件;
④ 达到include文件的结尾,离开include文件。 null第5章 TMS320C54x汇编语言程序设计5. 局部标号 【例5.1.4】合法、非法局部标号$n举例。 假设符号ADDRA,ADDRB,ADDRC已经在前面作了定义。 Label1: LD ADDRA,A
SUB ADDRB,A
BC $1,ALT
LD ADDRB,A
B $2
$1 LD ADDRA,A
$2 ADD ADDRC,A
.newblock
BC $1,ALT
STL A,ADDRC
$1 NOP ;将ADDRA装入累加器A
;减去地址B
;如果小于0,分支转移到$1
;否则将ADDRB装入累加器A
;分支转移到$2
;$1:将ADDRA装入累加器A
;$2:加上ADDRC
;取消$1的定义,使它可被再次使用
;若小于0,分支转移到$1
;存ACC的低16位到ADDRC .newblock .newblock BC $1,ALT ;若小于0,分支转移到$1
STL A,ADDRC ;存ACC的低16位到ADDRC
$1 NOP
;错误:$1被多次定义 null第5章 TMS320C54x汇编语言程序设计【例5.1.5】name?形式的局部标号的使用方法。 ;********************************************
; 局部标号’mylab’的第1个定义
;********************************************
NOP
mylab? NOP
B mylab?
;*******************************************
.copy“a.inc”
;*******************************************
mylab? NOP
B mylab?
;包括文件中有‘mylab’第2次定义 ;从包括文件中退出复位后,
‘mylab’的第3个定义 null第5章 TMS320C54x汇编语言程序设计【例5.1.5】name?形式的局部标号的使用方法。 ;********************************************
; 在宏中‘mylab’的第4个定义,
; 为了避免冲突,宏使用不同的名称空间
;********************************************
maymac .macro
mylab? NOP
B mylab?
.endm
;*******************************************
mymac
B mylab?
;宏调用。引用‘mylab'的第3个定义 ;既不被宏调用复位,也不与定义在
宏中的相同名冲突 null第5章 TMS320C54x汇编语言程序设计【例5.1.5】name?形式的局部标号的使用方法。 ;********************************************
; 改变段,允许‘mylab'的第5个定义
;********************************************
.sect “Secto_One”
NOP
mylab? .word 0
NOP
NOP
B mylab?
null第5章 TMS320C54x汇编语言程序设计【例5.1.5】name?形式的局部标号的使用方法。 ;********************************************
; .newblock伪指令,允许‘mylab'的第6个定义
;********************************************
.newblock
mylab? .word 0
NOP
NOP
B mylab?
null第5章 TMS320C54x汇编语言程序设计5.1.4 汇编源程序中的表达式 表达式可以是常数、符号,或者是由算术运算符分开的一系列常数和符号。
有效表达式的值: -32 768~32 767 影响表达式的主要因素: ① 圆括号( )。圆括号内的表达式最先计算; 不能用大括号{ }或中括号[ ]代替圆括号( )。 ② 优先级。’C54x汇编器使用与C语言相似的优 先级,优先级高的先计算; ③ 从左到右运算。具有相同的优先级,按从左 到右的顺序计算。 null第5章 TMS320C54x汇编语言程序设计5.1.4 汇编源程序中的表达式 1. 运算符 ’C54x汇编器使用与C语言相似的优先级。
取正(+)、负(-)和乘(*)比二进制形式有较高的优先级。 2. 条件表达式 汇编器支持关系运算符,可以用于任何表达式。 = 等于 = = 等于 != 不等于
> = 大于或等于 < = 小于或等于
> 大于 < 小于 null第5章 TMS320C54x汇编语言程序设计5.1.4 汇编源程序中的表达式 3. 有效定义的表达式 某些汇编器要求有效定义的表达式作为操作数。操作数是汇编时间常数或链接时可重定位的符号。
有效定义的表达式是指表达式中的符号或汇编时间常数在表达式之前就已经被定义。
有效定义的表达式的计算必须是绝对的。 null第5章 TMS320C54x汇编语言程序设计3. 有效定义的表达式 【例5.1.6】 有效定义的表达式。 .data
label1 .word 0
.word 1
.word 2
label2 .word 3
X .set 50h
goodsym1 .set l00h + X
goodsym2 .set $
goodsym3 .set label1
goodsym4 .set label2-label1; 将16位值0,1,2放入标号为
label1的当前段连续字中; 有效定义的表达式; 引用已定义的所有局部标号; 有效定义的表达式; 定义X的值; 将3放入标号为label2的字中null第5章 TMS320C54x汇编语言程序设计3. 有效定义的表达式 【例5.1.7】无效定义的表达式。 .global Y
badsym1 .set Y
badsym2 .set 50h + Y
badsym3 .set 50h + Z
Z .set 60h; 定义Y为全局外部符号; Y在当前文件中未定义 ; 无效的表达式; 无效的表达式,Z还未定义; 定义Z,但应在表达式使用之前null第5章 TMS320C54x汇编语言程序设计5.1.4 汇编源程序中的表达式 4. 表达式上溢和下溢 汇编时执行了算术操作以后,汇编器检查上溢和下溢的条件。当出现上溢或下溢时,汇编器会发出一个值被截断了的警告。
汇编器不检查乘法的溢出状态。 null第5章 TMS320C54x汇编语言程序设计5.1.4 汇编源程序中的表达式 5. 可重新定位符号和合法表达式 对于绝对符号、可重新定位符号以及外部符号的有效操作,可参见下表。 null第5章 TMS320C54x汇编语言程序设计5. 可重新定位符号和合法表达式 表达式不能包含可重新定位符号和外部符号的乘或除;
表达式中不能含有对其他的段为可重新定位的符号;
用.global伪指令定义为全局的符号和寄存器也可以用在表达式中。这些符号和寄存器被声明为外部符号;
可重新定位的寄存器也可以用在表达式中,这些寄存器的地址相对于定义它们的寄存器段是可重新定位的,除非将它们声明为外部符号。null第5章 TMS320C54x汇编语言程序设计5. 可重新定位符号和合法表达式 例如:在下面的程序中,使用了4个定义在相同段的符号。 .global extern_1
intern_1: .word ‘’’D’
LAB1: .set 2
intern_2: .word 3
LD #LAB1+((5+4)*3),A
LD #LAB1+3+(4*7),A .global extern_1
intern_1: .word ‘’’D’
LAB1: .set 2
intern_2: .word 3
LD #LAB1+((5+4)*3),A
LD #LAB1+3+(4*7),A;定义在外部的全局符号 ;定义在现行模块中,可重新定位 ;LAB1=2,绝对符号 ;定义在现行模块中,可重新定位 ;LAB1为绝对符号,A=29 ;LAB1为绝对符号,A=33 null第5章 TMS320C54x汇编语言程序设计5. 可重新定位符号和合法表达式 所有合法表达式可以化简为两种形式:
① 可重新定位符号±绝对符号;
② 绝对符号。
单操作数运算仅能应用于绝对符号,不能应用于可重新定位符号。
表达式简化为仅含有可重新定位符号是非法的。null第5章 TMS320C54x汇编语言程序设计5. 可重新定位符号和合法表达式 【例5.1.8】 判断下列指令中表达式的合法性。 LD extern_1-10,B
LD 10-extern_1,B
LD -(intern_1),B
LD extern_1/10,B
LD intern_1 + extern_1,B可重新定位 合法 不可将重新定位符号变负可重新定位符号不可变负 非法 可重新定位符号不可乘除 非法 可重新定位+可重新定位=非法 非法 非法 null第5章 TMS320C54x汇编语言程序设计5. 可重新定位符号和合法表达式 【例5.1.9】 判断下列指令中表达式的合法性。 LD intern_1 - intern_2 + extern_1,B
LD intern_1 + intern_2 + extern_1,B
LD intern_1 + extern_1 - intern_2,B可重新定位可重新定位可重新定义-可重新定义=绝对符号 绝对符号可重新定位绝对符号+可重新定位合法可重新定义+可重新定义=非法非法可重新定义+可重新定义=非法非法null第5章 TMS320C54x汇编语言程序设计5.2 堆栈的使用方法 当程序调用中断服务程序或子程序时,需要将程序计数器PC的值和一些重要的寄存器值进行压栈保护,以便程序返回时能从间断处继续执行。
’C54x提供一个用16位堆栈指针SP寻址的软件堆栈。
当向堆栈中压入数据时,堆栈是从高地址向低地址方向填入,堆栈指针SP先减1,然后将数据压入堆栈。
当从堆栈中弹出数据时。数据先从堆栈中弹出,然后堆栈指针SP加1。 null第5章 TMS320C54x汇编语言程序设计5.2 堆栈的使用方法 1. 堆栈的设置 size .set 120
stack .usect “STACK”,size
STM # stack + size,SP 在数据RAM空间开辟一个堆栈区。 在RAM中定义一个STACK
的保留空间,共120个单元 设置堆栈指针,# stack + size→SP。 保留区的高地址赋给SP,
作为堆栈的栈底 若程序中要使用堆栈,必须先进行设置,如: 设置好堆栈后,就可以使用堆栈了,如:
CALL pmad ;(SP)-1→SP,(PC)+2→TOS,pmad→PC
RET ;(TOS)→PC,(SP)+1→SP null第5章 TMS320C54x汇编语言程序设计2. 堆栈区大小的确定 ① 先开辟一个较大的堆栈区,用已知数充填,如: LD # -9224,B
STM # length,AR1
MVMM SP,AR4
loop: STL B,*AR4-
BANZ loop,*AR1- 堆栈区的大小可以按照以下步骤来确定: ;堆栈区要充填的数0DBF8h加载B
;设置循环次数
;设置数据指针AR4,SP→AR4
;循环,充填数据
DBF8DBF8DBF8……DBF8DBF8DBF8AR4→null第5章 TMS320C54x汇编语言程序设计2. 堆栈区大小的确定 ① 先开辟一个较大的堆栈区,用已知数充填。 堆栈区的大小可以按照以下步骤来确定: 6B140013…SP→② 运行程序,执行所有堆栈操作。 ③ 检查堆栈中的数值。 7AB3 用过的堆栈区就是实际需要的堆栈空间。用过的栈区null第5章 TMS320C54x汇编语言程序设计5.3 控制程序 ’C54x具有丰富的程序控制指令,利用这些指令可以执行分支转移、子程序调用、子程序返回,条件执行以及循环等控制操作。 5.3.1 分支操作程序 程序控制中的分支操作包括:
分支转移程序
子程序调用
子程序返回
条件操作程序 null第5章 TMS320C54x汇编语言程序设计5.3.1 分支操作程序 通过传送控制到程序存储器的其他位置,分支转移会中断连续的指令流。
分支转移指令可以改写PC值,使程序改变流向。其指令分为无条件分支转移和条件分支转移两类。两者都可以带延时操作和不带延时操作。 1. 分支转移程序 null第5章 TMS320C54x汇编语言程序设计 无条件分支转移:无条件执行分支转移;
条件分支转移:要在满足用户一个或多个条件时才执行分支转移;
远程分支转移:允许分支转移到扩展存储器。 1. 分支转移程序 【例5.3.1】 分支转移举例。
STM #88H,AR0
LD #1000H,A
zhong: SUB AR0,A
BC zhong,AGT,AOV
;将操作数#88H装入AR0
;将操作数#1000H装入ACC
;将A中的内容减去AR0中的
;内容结果装入A
;若累加器A>0且溢出,
;则转至zhong,否则往下执行 null第5章 TMS320C54x汇编语言程序设计5.3.1 分支操作程序 与分支转移一样,通过传送控制到程序存储器的其他位置,子程序调用会中断连续的指令流。但是与分支转移不同的是,这种传送是临时的。
当函数的子程序被调用时,紧跟在调用后的下一条指令的地址保存在堆栈中。这个地址用于返回到调用程序并继续执行调用前的程序。
子程序调用操作分成两种形式:无条件调用和条件调用,两者都可以带延时操作和不带延时操作。 2. 子程序调用程序 null第5章 TMS320C54x汇编语言程序设计2. 子程序调用程序 null第5章 TMS320C54x汇编语言程序设计2. 子程序调用程序 无条件调用是指无条件执行调用。
条件调用和无条件调用操作相同,但是条件调用要在满足一个或多个条件时才执行调用。
远程调用允许对扩展存储器的子程序或函数进行调用。 null第5章 TMS320C54x汇编语言程序设计2. 子程序调用程序 【例5.3.2】 子程序调用举例。 STM #123H,AR0
LD #456H,AR1
CALL new
LD AR1,16,A
new:MPY AR0,AR1,A
RET ;将操作数#123H装入AR0
;将操作数#456H装入AR1
;调子程序new
;将AR1的内容左移16位后装入A
;AR0与AR1的内容相乘,结果放入A中
;子程序返回 null第5章 TMS320C54x汇编语言程序设计5.3.1 分支操作程序 子程序返回程序可以使程序重新在被中断的连续指令处继续执行。
返回指令通过将弹出堆栈的值(包含将要执行的下一条指令的地址),送到程序计数器PC来实现返回功能。
’C54x可以执行无条件返回和条件返回,并且它们都可以带延时或不带延时操作。 3. 子程序返回程序 null第5章 TMS320C54x汇编语言程序设计3. 子程序返回程序 null第5章 TMS320C54x汇编语言程序设计3. 子程序程序 无条件返回是无条件执行返回操作。
条件返回可以给予被调用函数或中断服务程序(ISR)更多的返回方式,以便根据被处理的数据选择返回路径,通过使用条件返回指令来实现返回。
远程返回允许从扩展存储器的子程序或函数返回。 null第5章 TMS320C54x汇编语言程序设计5.3.1 分支操作程序 ’C54x的一些指令只有在满足一个或是多个条件后才被执行,如条件分支转移、条件调用和条件返回等指令。
这些指令都用条件来限制分支转移、调用和返回操作。这些条件可用条件算符来表示。 4. 条件操作程序 null第5章 TMS320C54x汇编语言程序设计4. 条件操作程序 null第5章 TMS320C54x汇编语言程序设计4. 条件操作程序 在条件操作时也可以要求有多个条件,只有所有条件满足时才被认为是满足条件。这种多个条件的组合就构成了指令的多重条件。 null第5章 TMS320C54x汇编语言程序设计4. 条件操作程序 选用多重条件时应当注意以下几点: ① 第1组:分为两类,最多可选择两个条件, 组内两类条件可以与/或构成多重条件,但不能用组内同类条件构成与/或多重条件。 ③ 组与组之间可用或构成多重条件。 当选择两个条件时,累加器必须是同一个。
例如,可以同时选择AGT和AOV,但不能同时选择AGT和BOV。 ② 第2组:分为三类,最多可选三个条件,可以在每类中各选一个条件进行与/或构成多重条件,但不能在同类选两个以上条件。 例如,可以同时测试TC、C和BIO,但不能同时测试NTC、C和NC。null第5章 TMS320C54x汇编语言程序设计4. 条件操作程序 【例5.3.3】 条件操作程序。 BC sub,BLEQ ; 条件分支转移
若累加器B≤0,则转至sub,
否则,往下执行
CC start,AGEQ,AOV ; 条件调用
若累加器A≥0且溢出,
则调用start,否则往下执行
RC NTC ; 条件返回
若TC = 0,则返回,否则往下执行 null第5章 TMS320C54x汇编语言程序设计4. 条件操作程序 注意: 若需要多个条件相与时,用单条指令表示。
如:BC new, AGT, AOV
转移条件:AGT和AOV的与逻辑 若需要两个条件相或时,需用两条指令分别表示。
如:若累加器A大于0或溢出,则转移至sub
转移条件:AGT和AOV的或逻辑
BC sub, AGT
BC sub, AOVnull第5章 TMS320C54x汇编语言程序设计5.3.1 分支操作程序 5. 比较转移程序 利用比较指令CMPR可实现比较转移操作。 比较操作指令:
CMPR 测试条件,辅助寄存器ARx
指令功能:辅助寄存器ARx与AR0进行比较,
若比较结果使所给定的测试条件成立,则TC位置1。
实现方法:① 通过CMPR的比较结果得TC值;
② 根据TC值,由条件转移指令实现分支转移。 null第5章 TMS320C54x汇编语言程序设计5. 比较转移程序 例如:比较操作后条件分支转移
STM #5,AR1 ; AR1=5
STM #10,AR0 ; AR0=10
loop: …
…
*AR1+ ; AR1=AR1+1
…
…
CMPR LT,AR1 ;若AR1-AR0<0,则TC=1,否则为0
BC loop, TC ;若AR1-AR0<0,则循环
若AR1=AR0,则顺序执行null第5章 TMS320C54x汇编语言程序设计5.3 控制程序 5.3.2 循环操作程序 在程序设计时,经常需要重复执行某一段程序。利用BANZ(当辅助寄存器不为0时转移)指令可实现循环计数和操作。 循环操作指令:
BANZ 转移地址,辅助寄存器
指令功能:当辅助寄存器不为0时,则转至转移地址,否则顺序执行。 null第5章 TMS320C54x汇编语言程序设计5.3.2 循环操作程序 【例5.3.4】 .bss x,10 ;给x保留10个空间
.bss y,1 ;给y保留1个空间
STM #x,AR1 ;设置数据段的首地址
STM #9,AR2 ;设置循环计数值
LD #0,A ;累加器清0
loop: ADD *AR1+,A ;累加运算,并修改地址
BANZ loop,*AR2- ;若计数值不为0,则循环,并计数值减1
若计数值为0,则结束循环
STL A, @y ;累加和存入y中 用AR2作为循环计数器,由BANZ实现程序的循环控制。注意: BANZ loop, *AR2- ;先判断,再修正AR2=AR2-1null第5章 TMS320C54x汇编语言程序设计5.4 算术运算程序 基本算术运算包括:
加减法和乘法运算
除法运算
长字和并行运算 null第5章 TMS320C54x汇编语言程序设计5.4 算术运算程序 5.4.1 加、减法和乘法运算 在数字信号处理中,加法和乘法运算是最常见的算术运算。【例5.4.1】 计算y = a x + b 程序:
LD @a, T ;取a值,T=a
MPY @x, B ;完成ax乘积,B=ax
ADD @b, B ;完成ax+b运算,B=ax+b
STL B, @y ;计算结果存入y中null第5章 TMS320C54x汇编语言程序设计5.4.1 加、减法和乘法运算 【例5.4.2】 计算y = xl al + x2 a2 程序:
LD @x1, T
MPY @a1, B
LD @x2, T
MAC @a2, B
STL B, @y
STH B, @y+1;T=x1
;B=x1a1
;T=x2
;乘法累加,B=x1a1+x2a2
;计算结果的低字BL存入y中
;计算结果的高字BH存入y+1中null第5章 TMS320C54x汇编语言程序设计5.4.1 加、减法和乘法运算 【例5.4.3】计算 y = 程序:
********************************************
* example.asm *
********************************************
.title “example.asm”
.mmregs
stack .usect “STACK”,10h
.bss a,4
.bss x,4
.bss y,1
.def start
.data ;为堆栈指定空间
;为变量分配9个字的空间null第5章 TMS320C54x汇编语言程序设计5.4.1 加、减法和乘法运算 【例5.4.3】计算 y = 程序: table: .word 1,2,3,4
.word 8,6,4,2
.text
start: STM #0,SWWSR
STM #STACK+10h,SP
STM #a,AR1
RPT #7
MVPD table,*AR1+
CALL SUM
end: B end ; 变量初始化
; 插入0个等待状态
; 设置堆栈指针
; AR1指向a
; 移动8个数据
; 从程序存储器到数据存