对上述程序稍作改动,程序的效率就高了(每次比较时执行的指令少了,速度就快了) PAIXU: NEXT: PUSH PUSH MOV MOV CLR MOV MOV MOV CJNE LOP1: JC CPL INC FPOS: MOV LOOP: INC MOV CJNE LOP2: JC CPL INC COMP: CJNE NEQ: JC XCH SJMP EXCH: SETB MOV DEC XCH INC MOV NEXCH: DJNZ DEC JBC POP POP RET ACC PSW PSW, #10H R3, #14 F0 ;进入循环前,清除交换标志F0 R0, #30H R2, 13H A,@R0 A, #80H, LOP1 FPOS A A B, A R0 A, @R0 A, #80H, LOP2 COMP A A A, B, NEQ EXCH A, B ;若不交换,则后>前,将后一绝对值(较大)送入B,作为下次比较的前一个绝对值 NEXCH F0 ;置位交换标志 A, @R0 ;借助ACC交换前后两个数 R0 A, @R0 R0 @R0, A R2, LOOP R3 ;每冒泡一次,比较次数-1 F0, NEXT PSW ACC
;绝对值排序,算法二
;入口参数:子程序名PAIXU2,影响ACC,寄存器B,2区寄存器R0, R2, R3, R4,标志位Cy,F0 ;出口参数:排序后数据仍放在30H开始的15个内部数据存储器单元中
PAIXU2: PUSH ACC ;保护现场 PUSH PSW MOV PSW, #10H ;设定2区寄存器区,同时0→F0 MOV R3, #14 ;暂存比较次数→R3 CLR F0 ;进入循环前,清除交换标志F0 NEXT: MOV R0, #30H ;首地址→R0 MOV R2, 13H ;当前比较次数(R3)→R2 LOOP: MOV A,@R0 ;取出前一个数 MOV R4, A ;前数送R4暂存 INC R0 ;R0指向下个数 MOV B, @R0 XRL A, B JB ACC.7, YH ; 如果前后数异号,转加法 TH: MOV A, R4 ; 如果前后数同号,则执行减法,将前数重新放入ACC CLR C ; SUBB A, B ;前数-后数 JZ NEXCH ; 差为0,即前绝对值=后绝对值,不交换 XRL A, B ;差值和减数异或,判断是否同号 JB ACC.7, NEXCH ;如果差值和减数异号,则前绝对值<后绝对值,不交换 SJMP EXCH ;如果同号(即上句不成立),则转前后交换 YH: MOV A, R4 ;前后数异号,执行加法,将前数重新放入ACC ADD A, B ; 前数+后数 JZ NEXCH ; 和为0,即前绝对值=后绝对值,不交换 XRL A, B ; 和与加数异或,判断是否同号 JNB ACC.7, NEXCH ;如果和与加数同号,则前绝对值<后绝对值,不交换 EXCH: SETB F0 ;前>后,交换位置,置标志F0 MOV A, @R0 ;后数→ACC DEC R0 ;R0指向前单元 XCH A, @R0 ;后数→前单元,前数→ACC INC R0 ;R0恢复指向后单元 MOV @R0, A ;前数→后单元 NEXCH: DJNZ R2, LOOP ;判断一次冒泡是否完成 DEC R3 ;修改每次冒泡中的比较次数 JBC F0, NEXT ;判断冒泡中有无交换,清除F0 POP PSW ;若上次冒泡中无交换,则排序完成 POP ACC RET
4-18 编制一子程序,将内部数据存储器30H~39H单元的数据连起来向左移动一位,39H最低位添0。 ;10个单元数据块左移一位子程序
;入口参数:子程序名MBRL1,数据块位于30H~39H单元,影响ACC,3区寄存器R0,标志位Cy ;出口参数:移位后数据仍位于30H~39H单元中 MBRL1: PUSH PSW ;保护PSW内容 PUSH ACC ;保护ACC内容 MOV PSW, #18H ;设置3区为当前工作寄存器区,同时清除Cy位 MOV R0, #39H ;数据块尾地址送R0 LOOP: MOV A, @R0 ;单元数据送ACC RLC A ;带进位左移 DEC R0 ;R0指向前一个单元
CJNE R0, #2FH ,LOOP ;判断R0是否已指向2FH(即30H已移位完成) POP ACC ;恢复ACC POP PSW ;恢复PSW RET ;返回 END
方法2:将上述子程序修改一下,可以适用m个单元左移n位的功能。 ;m个单元数据块左移n位子程序
;入口参数:子程序名MBRLN,数据块起始地址在R0中,数据块长度m放在R6中,移位数n放在R7中 ;影响ACC,寄存器B,标志位Cy
;出口参数:移位后R0指向数据块起始地址 MBRLN: PUSH PSW ;保护PSW内容 PUSH ACC ;保护ACC内容 PUSH B ;保护B内容 MOV B, R6 ;数据块长度m暂存入寄存器B NEXT: MOV R6, B ;数据块长度m重新赋值给R6 MOV A, R0 ADD A, R6 DEC A ;数据块首地址+m-1=数据块尾地址→ACC MOV R0, A ;R0指向数据块尾地址 CLR C ;清除Cy位 LOOP: MOV A, @R0 RLC A DEC R0 DJNZ R6 , LOOP ;内层循环完成m个单元左移一位 INC R0 ;使R0指向数据块首地址
DJNZ R7, NEXT ;外层循环完成n次移一位,即移动n位 POP B ;恢复现场 POP ACC POP PSW RET ;返回 END
第五章习题答案
5-1.中断申请信号如何才能被CPU检测到?
答:首先需中断系统开放(1→EA),然后相应的中断源需开放(即相关的标志EX0、ET0、EX1、ET1、ES、ET2需置1)
5-2.中断响应时CPU需要做哪些事情?
答:先将被响应的中断源所属的优先级存入优先级状态触发器;再将PC当前值(即断点)压入堆栈(先PCL,后PCH),然后将被响应中断源对应的中断入口地址送入PC。 5-3.中断入口与中断服务子程序入口有什么区别?
答:中断入口指的是当一个中断被响应时,由CPU自动调用的程序存储器的某个单元地址,这些地址是按不同中断源预先安排好的;而中断服务子程序入口指的是用户编制的中断服务子程序的第一条指令在程序存储器中存放的地址,两者一般来讲是不一样的,通常会在中断入口处安排一条跳转指令(LJMP或AJMP)指向中断服务子程序的入口。
5-4.89C52单片机中有哪些中断源?它们的中断申请标志分别是什么? 答:外部中断0,标志IE0 定时器/计数器T0中断,标志TF0 外部中断1,标志IE1 定时器/计数器T1中断,标志TF1 串行口中断,标志RI、TI 定时器/计数器T2中断,标志TF2、EXF2
5-5.若在某一个89C52单片机应用系统中,在系统初始化中将特殊功能寄存器IE和IP分别设置为10101111B和00101100B。当该系统正在运行时,问:
1) 如果外部中断1和定时器/计数器1同时申请中断,CPU将为哪一个中断源服务?为什么?
2) 如果CPU正在执行外部中断0的中断服务子程序,这时CPU还能响应系统哪些中断源的中断申请?为
什么?
提示:根据IE,IP的内容可知,当前开放的中断源为外部中断0,T0中断,外部中断1,T1中断,T2中断;其中外部中断1,T1中断,T2中断为高级中断,外部中断0,T0中断为低级中断。
答:1) 如果外部中断1和定时器/计数器1同时申请中断,CPU将为外部中断1服务,因为它们同属高级中断,而在硬件查询序列中外部中断1排在T1前。
2) 由于外部中断0为低级中断,所以它的中断过程可以被其它任何高级中断源打断,在此处即CPU还能响应外部中断1,T1,T2的中断申请。
5-6.若在某一个单片机应用系统中,有一个外部中断1,中断级别为低级中断,中断申请信号为脉冲信号,中断服务子程序的首地址为1100H,中断服务子程序的任务是将P1口的数据传递至外部数据存储器2400H单元。编制初始化程序及中断服务子程序。 ORG 0 ;主程序入口 LJMP MAIN ;跳转到用户程序 ORG 13H ;外部中断1入口 LJMP X1IPG ;跳转到中断服务子程序入口 ORG 100H ;用户程序入口地址 MAIN: MOV SP, #60H ;堆栈指针初始化
SETB IT1 ;外部中断1设为脉冲模式
SETB EA ;允许中断 SETB ET1 ;开放外部中断1 CLR PT1 ;外部中断1设为低级中断 SJMP $ ;主程序原地等待,等待中断发生(即表示CPU可以做任何其它事情)
相关推荐: