复习资料10.docx
《复习资料10.docx》由会员分享,可在线阅读,更多相关《复习资料10.docx(16页珍藏版)》请在冰点文库上搜索。
复习资料10
第三章
(1)加法指令举例
【例3.1】ADD*AR3+,14,A;将AR3所指的数据存储单元内容,左移14位与A相加,结果放A中,AR3加1。
(2)减法指令(13条)《表3.3.5》
说明:
①SUBS用于无符号数的减法运算;
SUBB用于带借位的减法运算(如32位扩展精度的减法);
SUBC为条件减法.SUBCSmen,Src
②使用SUBC重复16次减法,就可以完成除法功能。
被除数-(除数<<15):
够减:
被除数左移,商+1;不够减:
被除数左移,商+0;
注:
被除数和商共用一个R→B:
随着B的左移被除数逐渐退出,商从右→左逐渐进入。
减法指令举例
【例3.2】利用SUBC完成整数除法(TEMP1/TEMP2)
LDTEMP1,B;将被除数TEMP1装入B累加器的低16位
RPT#15;重复SUBC指令16次
SUBCTEMP2,B;使用SUBC指令完成除法
STLB,TEMP3;将商(B累加器的低16位)存入变量TEMP3
STHB,TEMP4;将余数(B累加器的高16位)存入变量TEMP4
(3)乘法指令(10条)《表3.3.6》
说明:
①不同的乘法指令完成不同的功能
MPY:
普通乘指令;MPYR:
带四舍五入指令;MPYA:
A累加器高端参与乘法;
MPYU:
无符号乘法;SQUR:
平方;
②小数乘法:
将FRCT设置为1,系统自动将乘积结果左移1位。
【例3.3】MPYSmen,dst;T*Smem→A,Smem所在的单数据存储器地址为13(0Dh)
例如:
MPY13,A
(4)乘加和乘减指令(15条)《表3.3.7》
【例3.3】MAC*AR5+,A;A+(AR5)*T→A,AR5=AR5+1
(5)长操作数指令(6条)《表3.3.8》
【例3.4】DADDLmen,src[,dst];IfC16=0dst=Lmem+src(长字运算:
AR3+2)
例如:
DADD*AR3+,A,B
【例3.8】CMPMSmen,#1k;比较Smem与常数1k是否相等,若相等TC=1,否则TC=0
例如:
CMPM*AR4+,0404h
说明:
FIRSXmem,Ymem,pmad;B=B+A*pmad/A=(Ymem+Xmem)<<16《表3.3.9》
•FIRS指令实现一个对称的有限冲激响应(FIR)滤波器。
•Xmem和Ymem相加后的结果左移16位放入累加器A中。
在下一个循环中,pmad加1。
•累加器A的高端(32~16位)和由pmad寻址得到的Pmem相乘,乘法结果与累加器B相加并存放在累加器B中。
•一旦循环流水线启动,指令成为单周期指令。
指令受OVM,FRCT和SXM状态标志位的影响,执行结果影响C、OVC和OVB。
【例3.5】FIRS*AR3+,*AR4+,COEFFS
(1)分支指令(6条)《表3.3.15》
【例3.9】BANZ[D]pmad,Sind
若当前辅助寄存器ARx不为0,则pmad值赋给PC,否则PC值加2。
若为延迟方式,此时紧跟该指令的两条单字指令或一条双字指令先被取出执行,然后程序再跳转。
该指令不能被循环执行。
如:
BANZ2000h,*AR3-
(2)调用和返回指令(10条)《表3.3.16\18》
【例3.10】CALL[D]pmad
返回地址压入栈顶(TOS)保存,无延时时返回地址为PC+2,有延时时返回地址为PC+4(延时2字);
将pmad值赋给PC实现调用。
如:
CALL3333h
(3)重复指令(5条)《表3.3.25》
【例3.12】RPTB[D]pmad;块循环指令。
循环次数必须在指令执行前装入BRC。
执行命令时,块循环起始寄存器RSA装入PC+2(若有D后缀时为PC+4),块循环尾地址寄存器REA中装入pmad。
(RSA=PC+2[4],REA=pmad-1。
)
ST#99,BRC;循环计数器赋值
RPTBend_block-1;end_block为循环块的底部
4)中断指令(2条)《表3.3.17》
【例3.12】INTR3;(即K=3)
•将PC值压入栈顶;
•由K确定的中断向量赋给PC,执行该中断服务子程序。
•中断标志寄存器(IFR)对应位清零且INTM=1(禁止可屏蔽中断)。
第四章
【例4.1】汇编语言程序编写方法举例
.title“example.asm”;用双引号括起的源程序名
.mmregs;定义存储器映射寄存器的替代符号
STACK.usect“STACK”,10H;在数据存储器中留出16个单元作为
;堆栈区,名为STACK
.bssa,4
.bssx,4;在数据存储器中空出4个存储单元存放
;变量x1,x2,x3和x4.
.bssy,1
.defstart;在此模块中定义,可为别的模块引用
.data;紧跟其后的是已初始化数据
table:
.word1,2,3,4;在程序存储器标号为table开始的8个单
.word8,6,4,2;元存放初始化数据
.text;紧跟其后的是汇编语言程序正文
start:
STM#0,SWWSR;addsnowaitstates
STM#STACK+10H,SP;setstackpointer
STM#a,AR1;AR1pointtoa
RPT#7;move8values
MVPDtable,*AR1+;fromprogrammemoryintodatamemory
CALLSUM;callSUMsubroutine
end:
Bend
SUM:
STM#a,AR3;Thesubroutineimplement
STM#x,AR4;multiply-accumulate
RPTZA,#3;重复执行下一条指令,并对ACC清0
MAC*AR3+,*AR4+,A
STLA,@y
RET
.end;结束汇编,汇编器将忽略此后的任何源语句
【例4.12】计算
.bssx,5;为变量分配6个字的存储空间
.bssy,1
STM#x,AR1;AR1指向x
STM#4,AR2;设AR2初值为4
LD#0,A
loop:
ADD*AR1+,A
BANZloop,*AR2-;当AR2不为0时转移,AR2-1→AR2
STLA,@y
本例中用AR2作为循环计数器,设初值为4,共执行5次加法。
也就是说,应当用迭代次数减1后加载循环计数器。
【例4.13】对数组进行初始化。
x[5]={0,0,0,0,0}
主要程序(部分)如下:
.bssx,5
STM#x,AR1
LD#0,A
RPT#4
STLA,*AR1+
或者
.bssx,5
STM#x,AR1
RPTZA,#4
STLA,*AR1+
【例4.14】对数组x[5]中的每个元素加1。
.bssx,5
begin:
LD#1,16,B
STM#4,BRC;BRC赋值为4
STM#x,AR4
RPTBnext-1;next-1为循环结束地址
ADD*AR4,16,B,A
STHA,*AR4+
next:
LD#0,B
…
用next-1作为结束地址是恰当的。
如果用循环回路中最后一条指令(STH指令)的标号作为结束地址,若最后一条指令是单字指令也可以,若是双字指令,就不对了。
【例4.15】编写一段程序,首先对数组x[20]赋值,再将数据存储器中的数组x[20]复制到数组y[20]。
.title“exp15.asm”
.mmregs
STACK.usect“STACK”,30h
.bssx,20
.bssy,20
.data
table:
.word1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
.defstart
.text
Start:
STM#x,AR1
RPT#19
MVPDtable,*AR1+;程序存储器传送到数据存储器
STM#x,AR2
STM#y,AR3
RPT#19
MVDD*AR2+,*AR3+;数据存储器传送到数据存储器
end:
Bend
.end
/exp15.cmd*/链接命令
vectors.obj
exp15.obj
-oexp15.out
-mexp15.map
-estart
MEMORY
{
PAGE0:
EPROM:
org=0E000hlen=01F80h
VECS:
org=0FF80hlen=00080h
PAGE1:
SPRAM:
org=00060hlen=00030h
DARAM:
org=00090hlen=01380h
}
SECTIONS
{
.vectors:
>VECSPAGE0
.text:
>EPROMPAGE0
.data:
>EPROMPAGE0
.bss:
>SPRAMPAGE1
.STACK:
>DARAMPAGE1
}
实现20个数据先从EPROM的0E000Hh~0E013h传送到数据存储器SPRAM的0060h~0073h单元,实现数据的初始化,再从0060h~0073h单元传送到0074h~0087h单元,实现数据搬移,其示意图如图4.7所示。
注意,实际看到的是十六进制数。
1、**单字运算
【例4.16】试编一程序,计算
的值,并找出4项乘积
aixi(i=1,2,3,4)中的最大值,放入累加器A中。
.title“exp16.asm”
.mmregs
STACK.usect“STACK”,10h;堆栈的设置
.bssa,4;为变量分配10个字的存储空间
.bssx,4
.bssy1,1
.bssy2,1
.defstart
.data
table:
.word1,5,3,4
.word8,6,7,2
.text
start:
STM#0,SWWSR;插入0个等待状态
STM#STACK+10h,SP;设置堆栈指针
STM#a,AR1
RPT#7
MVPDtable,*AR1+
CALLSUM;调用乘累加子程序
CALLMAX;调用求最大值子程序
End:
Bend
SUM:
STM#a,AR3
STM#x,AR4
RPTZA,#3
MAC*AR3+,*AR4+,A
STLA,@y1;变量y1存放乘累加的值
RET
MAX:
STM#a,AR1
STM#x,AR2
STM#2,AR3
LD*AR1+,T
MPY*AR2+,A;第一个乘积在累加器A中
Loop:
LD*AR1+,T
MPY*AR2+,B;其他乘积在累加器B中
MAXA;累加器A和B比较,选大的存在A中
BANZloop,*AR3-;此循环中共进行3次乘法和比较
STLA,@y2;变量y2存放的最大值
RET
.end
假设.bss为变量a、x和y分配的10个字的存储空间,以数据存储器的0060H为起始地址,结果y1=67(43h),最大值y2=30(1Eh)。
**【例4.17】实现16位定点加减法、16位定点乘法、16位定点整数除法的程序。
.title“exp17.asm”
DAT0.set60h
DAT1.set61h
DAT2.set62h
DAT3.set63h
.text
ADD3.macroP1,P2,P3,ADDRP;宏定义:
ADDRP=P1+P2+P3
LDP1,A
ADDP2,A
ADDP3,A
STLA,ADDRP
.endm
_c_intoo:
Bstart
Start:
LD#000h,DP
STM#1000h,SP
SSBXINTM
Bk0:
ST#0012h,DAT0
LD#0023h,A
ADDDAT0,A
NOP
Bk1:
ST#0054h,DAT0
LD#0002h,A
SUBDAT0,A
NOP
Bk2:
ST#0345h,DAT0
STM#0002h,T
MPYDAT0,A
NOP
Bk3:
ST#1000h,DAT0
ST#0041h,DAT1
RSBXSXM
LDDAT0,A
RPT#15
SUBCDAT1,A
STLA,DAT2
STHA,DAT3
NOP
.end
bk5:
ST#0034h,DAT0
ST#0243h,DAT1
ST#1230h,DAT2
ADDDAT0,DAT1,DAT2,DAT3;宏调用DAT3=DAT0+DAT1+DAT2
NOP
.end
程序执行时,可在NOP指令处加断点,当执行到这条加了断点的语句时,程序将自动暂停。
可以通过“存贮器窗口”或“寄存器窗口”检查计算结果。
实验。
加法结果:
A=0000,0000,35h
减法结果:
A=FFFF,FFFF,Aeh
乘法结果:
A=0000,0006,8Ah
除法结果:
商DAT3=003Fh,余数DAT3=0001h
第六章
【例6.1】利用定时器Timer0在XF引脚产生周期为1s的方波。
分析:
设f=100MHz,
定时最大值是:
10(ns)*24*216=10(ms),
要输出1s的方波,1和0分别为500ms。
可定时5ms,再在中断程序中加个100计数器,
定时器周期=10ns×(1+9)×(1+49999)=5ms。
CounterSet.set100;定义计数次数
PERIOD.set49999;定义计数周期
.asgAR1,Counter;AR1做计数指针,重
新命名以便识别
STM#CounterSet,Counter;设计数器初值
STM#0000000000010000B,TCR;停止计数器
STM#PERIOD,TIM;给TIM设定初值49999
STM#PERIOD,PRD;PRD与TIM一样
STM#0000001001101001B,TCR;开始定时器
STM#0008H,IMR;开TIME0的中断
RSBXINTM;开总中断
End:
NOP
BEnd
中断服务程序:
TINT0_ISR
TINT0_ISR:
PSHMST0;保护ST0,因要改变TC
BANZNext,*Counter-;计数器不为0,计数器减1,退出中断
STM#CounterSet,Counter;
BITF*AR2,#1;数器为0,根据当前XF的状态,
;分别到setXF或ResetXF
BCResetXF,TC计
setXF:
SSBXXF;置XF为高
ST#1,*AR2
BNext
ResetXF:
RSBXXF;置XF为低
ST#0,*AR2
Next:
POPMST0
RETE
End