《51单片微型机原理和接口教程》(周思跃)习题解答

发布时间 : 星期一 文章《51单片微型机原理和接口教程》(周思跃)习题解答更新完毕开始阅读

;入口参数:子程序名PAIXU,影响ACC,寄存器B,2区寄存器R0, R2, R3, 标志位Cy,F0

;出口参数:排序后数据仍放在30H开始的15个内部数据存储器单元中 PAIXU: 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 ;取出前一个数 CJNE A, #80H, LOP1 ;判断正负 LOP1: JC FPOS ;如果为正数,则不转换 CPL A ;如果是负数,取相反数补码 INC A ;即得负数的绝对值 FPOS: MOV B, A ;前数的绝对值→B INC R0 ;R0指向下个数 MOV A, @R0 CJNE A, #80H, LOP2 LOP2: JC COMP ; 如果是负数,取相反数补码 CPL A

INC A ; 后数的绝对值→ACC

COMP: CJNE A, B, NEQ ;比较前后两绝对值 SJMP NEXCH ;后=前,不交换 NEQ: JNC NEXCH ;后>前,不交换 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

对上述程序稍作改动,程序的效率就高了(每次比较时执行的指令少了,速度就快了)

PAIXU: PUSH ACC PUSH PSW

NEXT:

PSW, #10H

R3, #14 F0 ;进入循环前,清除交换标志F0 R0, #30H R2, 13H A,@R0

A, #80H, LOP1

LOP1: FPOS A A FPOS: B, A LOOP: R0 A, @R0

A, #80H, LOP2

LOP2: COMP A

A

COMP: A, B, NEQ NEQ: EXCH

A, B ;若不交换,则后>前,将后一绝对值(较大)送入B,作为下次

比较的前一个绝对值 SJMP NEXCH EXCH: SETB F0 ;置位交换标志 MOV A, @R0 ;借助ACC交换前后两个数 DEC R0 XCH A, @R0 INC R0 MOV @R0, A NEXCH: DJNZ R2, LOOP DEC R3 ;每冒泡一次,比较次数-1 JBC F0, NEXT POP PSW POP ACC

RET

;绝对值排序,算法二

;入口参数:子程序名PAIXU2,影响ACC,寄存器B,2区寄存器R0, R2, R3, R4,标志位Cy,F0

;出口参数:排序后数据仍放在30H开始的15个内部数据存储器单元中 PAIXU2: PUSH ACC ;保护现场 PUSH PSW MOV PSW, #10H ;设定2区寄存器区,同时0→F0

MOV

MOV CLR MOV MOV MOV CJNE JC CPL INC MOV INC MOV CJNE JC CPL INC CJNE JC XCH

NEXT: LOOP:

MOV R3, #14 ;暂存比较次数→R3 CLR F0 ;进入循环前,清除交换标志F0 MOV R0, #30H ;首地址→R0 MOV R2, 13H ;当前比较次数(R3)→R2 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检测到?

联系合同范文客服:xxxxx#qq.com(#替换为@)