第4章 指令系统4 stc15f2k60s2单片机的指令系统 例题.pdf
12页51 第 4 章STC15F2K60S2 单片机的指令系统 例题例题 例 4.1分析执行下列指令序列后各寄存器及存储单元的结果 MOVA,#30H MOV4FH,A MOVR0,#20H MOV@R0,4FH MOV21H,20H MOVDPTR,#3456H 解:分析如下: MOVA,#30H; (A)=30H MOV4FH,A; (4FH)=30H MOVR0,#20H; (R0)=20H MOV@R0,4FH;((R0)) =(20H)=(4FH)=30H MOV21H,20H; (21H)=(20H)=30H MOVDPTR,#3456H; (DPTR)=3456H 所以执行程序段后: (A)=30H, (4FH)=30H, (R0)=20H, (20H)=30H, (21H)=30H, (DPTR)=3456H 52 例 4.2将扩展 RAM 2010H 中内容送扩展 RAM 2020 单元中,用 Keil C 集成开发环境 进行调试 解: (1)编程如下: ORG0 MOVDPTR,#2010H;将 16 位地址 2010H 赋给 DPTR MOVXA,@DPTR;读扩展 RAM 2010H 中数据至累加器 A MOVDPTR,#2020H;将 16 位地址 2020H 赋给 DPTR MOVX@DPTR,A;将累加器 A 中数据送入外 RAM 2020H 中 END (2)按第 4 章所学知识,编辑文件与编译好上述指令,进入调试界面,设置好被传送地 址单元的数据,如 66H,如图 4.6 所示。
图 4.6 程序执行前,设置 2010H 地址单元内容与 2020H 地址单元的状态 单步或全速执行这 4 条指令,观察程序执行后 2010H 地址单元内容的变化 53 图 4.7 程序执行后,2010H 地址单元内容与 2020H 地址单元内容的变化 从图 4.6 和图 4.7 可知, 传送指令执行后, 传送目标单元的内容与被传送单元的内容一致, 同时,被传送单元的内容也不会改变 54 例 4.3 将扩展 RAM 2000H 中的数据送到片内 RAM 30H 单元中去 解:编程如下: MOVDPTR,#2000H;将 16 位地址 2000H 赋给 DPTR MOVXA,@DPTR;读扩展 RAM 2010H 中数据至累加器 A MOVR0,#30H;设定 R0 指针,指向基本 RAM30H 单元 MOV@R0, A;扩展 RAM 2000H 中的数据送到片内基本 RAM 30H 单元 例 4.4将程序存储器 2010H 单元中的数据传送到累加器 A 中 (设程序的起始地址为 2000H) 解: 方法一: ORG2000H;伪指令,指定后面程序的存放起始地址 MOVDPTR,#2000H MOVA,#10H MOVCA,@A+DPTR 编程技巧:在访问前,必须保证(A)+(DPTR)等于访问地址,如该例中的 2010H, 一般方法是访问地址低 8 位值(10H)赋给 A,剩下的 16 位地址(2010H-10H=2000H)赋 给 DPTR。
编程与指令所在的地址无关 方法二: ORG2000H MOVA,#0DH MOVCA,@A+PC 分析:因为程序的起始地址为 2000H,第一条指令为双字节指令,则第二条指令的地址 为 2002H,第二条指令的下一条指令的首字节地址应为 2003H,即(PC)=2003H,因为(A) +(PC)=2010H,故(A)=0DH 因该指令与指令所在地址有关,不利于修改程序,故不建议使用 55 例 4.5设(A)=40H,(B)=41H,分析执行下列指令序列后的结果 解:分析如下: MOVSP,#30H;(SP)=30H PUSHA;(SP)=31H, (31H)=40H ,(A)=40H PUSHB;(SP)=32H, (32H)=41H ,(B)=41H MOVA,#00H;(A)=00H MOVB,#01H;(B)=01H POPB;(B)=41H, (SP)=31H,(B)=41H POPA;(A)=40H, (SP)=30H,(A)=40H 执行后: (A)=40H, (B)=41H, (SP)=30H,A 和 B 中的内容恢复原样入栈操作、 出栈操作主要用于子程序、中断服务程序中,入栈操作用来保护 CPU 现场参数,出栈操作用 来恢复 CPU 现场参数。
例 4.6试编制 4 位十六进制数加法程序,假定和数超过双字节,要求如下: (21H) (20H)+(31H) (30H)→ (42H) (41H) (40H) 解:分析:先做低字节不带进位求和,再做带进位高字节求和,最后处理最高位 (21H) (20H) +(31H) (30H) (42H) (41H) (40H) 参考程序如下: ORG0000H LJMPSTART ORG0100H START: MOVA,20H ADDA,30H;低字节不带进位加法 MOV40H,A MOVA,21H ADDCA, 31H;高字节带进位加法 MOV41H,A MOVA,#00H;最高位处理:0+0+(CY) ADDCA,#00H MOV42H,A SJMP$;原地踏步,作为程序结束命令 END 56 例 4.7 编制下列减法程序,设够减,要求如下: (31H) (30H)-(41H) (40H)→ (31H) (30H) 解:先做低字节不带进借位求差,再做高字节带借位求差 编程如下: ORG0000H LJMPSTART ORG1000H START: CLRC`;CY 清零 MOVA,30H;取低字节被减数 SUBBA,40H;被减数减去减数,差存 A MOV30H,A;存差低字节 MOVA,31H;取高字节被减数 SUBBA,41H;被减数减去减数,差存 A MOV31H,A;存差高字节 SJMP$ END 57 例 4.8试编制十进制数加法程序(单字节 BCD 加法) ,并说明程序运行后 22H 单元的 内容是什么?运算要求如下: 56+38→ (22H) 解:编程如下: ORG0000H LJMPSTART ORG1000H START: MOVA,#56H ADDA,#38H DAA MOV22H,A SJMP$ END 分析如下: 0101 011056 +0011 100038 1000 1110 +0110低 4 位加 6 调整 1001 010094 所以,22H 单元的内容为 94H,即十进制数 94(56+38) 。
58 例 4.9编程实现单字节的十进制数减法程序,假定够减,要求: (20H)-(21H)→ (22H) 解:51 单片机指令系统中无十进制减法调整指令,减法的十进制运算,需要通过加法来 实现的,即被减数加上减数的补数,再十进制加法调整既可 编程如下: ORG0000H CLRC MOVA,#9AH;减数的补数为 100-减数 SUBBA,21H ADDA,20H;被减数与减数的补数相加 DAA;十进制加法调整 MOV22H,A;存十进制减法结果 SJMP$ END 59 例 4.10将累加器 A 的 1,3,5,7 位清 0,其它位置 1,送入片内 RAM 20H 单元中 解:编程如下: ANLA,#55H;将 A 的 1、3、5、7 位清 0 ORLA,#55H;将 A 的 0、2、4、6 位置 1 MOV20H,A 例 4.11 设(A)=ACH,要求将第 0、1 位取反,第 2、3 位清零,第 4、5 为置“1” ,第 6、 7 位不变 解:编程如下: XRLA, #00000011B;(A)=10101111 ANLA, #11110011B;(A)=10100011 ORLA, #00110000B;(A)=10110011 例 4.12 编程将扩展 RAM 30H 单元内容的高 4 位不变低 4 位取反, 试编出它的相应程序。
解:编程如下: MOVR0,#30H;扩展 RAM 地址 30H 送 R0 MOVXA, @R0;取 RAM 30H 单元内容 XRLA, #0FH;低 4 位与“1”异或,实施取反操作 MOVX@R0, A;送回扩展 RAM30H 单元 例 4.13已知某单片机监控程序地址为 2080H,试问您用什么办法可使单片机开机后自 动执行监控程序 解:单片机开机后程序计数器 PC 总是复位成全 0,即(PC)=0000H因此,为使机器 开机后能自动转入 2080H 处执行监控程序,则在 0000H 处必须存放一条如下指令: LJMP2080H 60 例 4.14 将扩展 RAM 的一个数据块(首地址为 DATA1)传送到内部基本 RAM(首地址 为DATA2) ,遇到传送的数据为零时停止传送,试编程 解: ORG0000H MOVR0,#DATA2;设置基本 RAM 指针 MOVDPTR,#DATA1;设置扩展 RAM 指针 LOOP1: MOVXA,@DPTR;取被传送数据 JZLOOP2;不为 0,数据传送,为 0,结束传送 MOV@R0,A;数据传送 INCR0;修改指针,指向下一个操作数 INCDPTR SJMPLOOP1;重新进入下一个传送流程 LOOP2: SJMPLOOP2;程序结束(原地踏步) END 例 4.15编程实现如下功能: (A)>10H(R0)=01H (A)=10H(R0)=00H (A)<10H(R0)=02H 解:编程如下: ORG0000H CJNEA, #10H,NO_EQUAL MOVR0,#00H SJMPHERE NO_EQUAL: JCLESS MOVR0,#01H SJMPHERE LESS: MOVR0,#02H HERE: SJMPHERE END 61 例 4.16编程将扩展 RAM 1000H 开始的 100 个单元中分别存放 0~99。
解:编程如下: ORG 0000H MOVR0,#64H;设定循环次数 MOVA,#00H;设置预置数初始值 MOVDPTR,#1000H;设置目标操作数指针 LOOP: MOVX@DPTR,A;对指定单元置数 INCA;预置数加 1 INCDPTR;指向下一个目标操作数地址 DJNZR0,LOOP;判断循环是否结束 SJMP$ END 例 4.17 已知(SP)=60H,分析执行下列指令后的结果: ① 1000H:ACALL1100H ② 1000H:LCALL0800H 解: ① (SP)=62H, (61H)=02H, (62H)=10H, (PC)=1100H ② (SP)=62H, (61H)=03H, (62H)=10H, (PC)=0800H 62 例 4.18试编程实现将位地址 00H 位内容和位地址 7FH 位内容相互交换的程序 解:编程如下: ORG0000H MOVC,00H;取位地址 00H 的值送 CY MOV01H,C;暂存在位地址 01H 中 MOVC,7FH;取位地址 7FH 的值送 CY MOV00H,C;存在位地址 00H 中 MOVC,01H;取暂存在位地址 01H 中的值送 CY MOV7FH,C;送位地址 7FH 中 SJMP$ END 。





