MOV @R0,#33H MOV @R1,#44H MOV A,@R0 PUSH ACC MOV A,@R1 PUSH ACC NOP
POP ACC MOV @R0,A POP ACC MOV @R1,A NOP
SJMP $ END
;(30H)=? ;(40H)=? ;A=?
;SP=? (61H)=? ;A=?
;SP=? (62H)=?
;SP=? A=? ;(30H)=? ;SP=? A=? ;(40H)=?
③ 选择Project下的Rebuild all target files 对工程文件进行汇编和连接,如果出错,系统会提示出错并指出出错地方和出错类型,请按照提示返回程序进行修改,直到系统提示0 warnings,0 errors,表明程序没有语法错误,成功完成了汇编过程,就可以进行动态调试了。
④ 选择Project下的Options for target ‘Target1’进行动态调试的参数设置,点击debug,再点击 Use Simulator,最后点击完成。
⑤ 对程序进行动态调试,学会查看和修改相关寄存器(左边的register窗)、内部和外部存储器的内容。常用的工具条上的命令有开始/暂停动态调试,单步执行或,执行到光标处等。查看存储器内容的方式是在存储区(View/memory 窗)的地址栏内写上要查看的初始地址就可以了。比如看内部存储器用D:0000H,程序存储器用C:0000H,外部存储器用X:0000H。将每行程序执行后的结果写到该行程序的注释部分。
2、编写一个数据填充和数据块搬移程序。
仿照实验内容和步骤1的过程,建立、编辑、汇编、连接和动态调试程序,查看和验证数据区的内容是否正确。
ORG 0000H LJMP MAIN ORG 0100H
MAIN: MOV R0,#30H ; R0指向30H单元
MOV R2,#16 ; R2作循环计数器 NEXT1: MOV @R0,#'*' ; 填充当前单元
INC R0 ; 指针下移一个单元 DJNZ R2,NEXT1 ; 未填完16个单元,继续 ;以下程序将30H开始的16个字节内容送到100H开始的外部存储器中
MOV R1,#30H MOV DPTR,#0100H MOV R3,#10H NEXT2: MOV A,@R1
MOVX @DPTR,A INC R1 INC DPTR
9
DJNZ SJMP END R3,NEXT2 $
3、编写一个双字节算术加法程序。仿照实验内容和步骤1的过程,建立、编辑、汇编、连接和动态调试程序,将运行结果写到程序的注释部分。
MAIN:
ORG LJMP ORG MOV MOV MOV MOV MOV MOV ADD MOV MOV ADDC MOV MOV ADDC MOV SJMP END
0000H MAIN 0100H SP,#60H R1,#12H R0,#34H R2,#21H R3,#0EFH A,R0 A,R2 R4,A A,R1 A,R3 R5,A A,#0 A,#0 R6,A $
; R1R0=? ; R3R2=? ; 低8位相加
; 高8位相加
; R6R5R4=?
五、注意事项
1、源程序中的数字0切勿输成字母O,标点都要使用西文字符。 2、本次实验无需使用实验箱。 六、作业及预习要求
1、认真分析实验程序中各条指令的具体功能。 2、总结单片机程序设计与调试的一般流程。
3、对程序3进行修改,实现两个双字节BCD码的加法和减法。
10
实验二 程序设计实验
实验名称:程序设计实验 学时安排:4学时 实验类别:验证性 实验要求:必做 一、实验目的和任务
1、掌握分支、循环结构程序以及子程序的设计方法。 2、进一步熟悉Keil C51集成开发环境。 二、实验原理简介
在汇编语言程序设计中,普遍采用结构化程序设计方法。因为任何复杂的程序都可由顺序结构、分支结构及循环结构等构成。每种结构只有一个入口和出口,整个程序也只有一个入口和出口。结构化程序设计的特点是程序的结构清晰、易于读写和验证、可靠性高。结构化程序设计的基本方法有顺序结构、分支结构、循环结构、子程序。
本实验在实验一基础上,要求掌握分支、循环结构程序以及子程序的设计方法。 三、实验设备
PC 机一台(已安装Keil uVision软件) 四、实验内容和步骤
1、分支程序:
分支程序是根据要求无条件或有条件地改变程序执行流向。编写分支程序主要在于正确使用转移指令。
设变量x以补码形式存放在片内RAM的30H单元中,变量y与x的关系如下:
x?0?x?y??20H x?0
?x?5x?0?仿照实验一的过程,编写程序、汇编、连接和软件仿真。
MAIN: NEXT: ED:
ORG JMP ORG MOV MOV JZ ANL JZ MOV ADD MOV SJMP MOV SJMP END
0000H MAIN 0100H
30H, A, 30H
NEXT ;x=0,转移 A, #80H ;保留符号位 ED ;x >0,转移 A, #05H ;x <0,不转移 A, 30H 30H, A ED
30H, #20H $
11
图3.2.1 程序1流程图
图3.2.2 循环程序流程图
2、循环程序:循环程序一般包含四部分:初始化部分、循环处理部分、循环控制部分和循环修改部分。下面分别介绍这四个组成部分。
1) 初始化部分:设置循环开始的初始值,为循环做准备。 2) 循环处理部分:循环程序中重复执行的内容。 3) 循环控制部分:判断是否结束循环。
4) 循环修改部分:修改循环参数,为执行下一次循环做准备。 设有一带符号的数组存放在内部RAM以20H为首址的连续单元中,数组长度为30,要求找出其中的最大值,并将其存放到内部RAM的1FH单元中。
请自行填写循环程序写入数组并运行以下程序,观察结果。
MAIN:
MOV R0, #20H ;置取数指针R0初值
12
MOV B, #29H ;置循环计数器B初值 MOV A, @R0 ;第一个数送A LOOP: INC R0 ;修改指针 MOV R1, A ;暂存
XRL A, @R0 ;两数符号相同? JB ACC.7, LAT ;若相异,则转LAT
MOV A, R1 ;若相同,则恢复A中原来值 CLR C ;C清零
SUBB A, @R0 ;两数相减,以判断两者的大小 JNB ACC.7, AA ;若A中值为大,则转AA
CXA: MOV A, @R0 ;若A中值为小,则将大数送入A SJMP BB
LAT: XRL A, @R0 ;恢复A中原值MOV A, R1 JNB ACC.7, BB ;若A中值为正,侧转BB SJMP CXA ;若A中值为负,则转CXA AA: MOV A, R1 ;恢复A中原值 BB: DJNZ B, LOOP
MOV 1FH, A ;最大者送1FH单元 END
3、子程序:同一个程序中,往往有许多地方都需要执行同一任务,这时可对这项任务独立编写,形成一个子程序。在原来的主程序中需要执行该任务时,调用该子程序,执行完后又返回主程序,这就是子程序结构。在程序设计过程中,适当地使用子程序具有以下优点:
1)不必重复编写同样的程序,提高了编码的效率。
2)缩短了源程序和目标程序的长度,节省了程序存储器的空间。 3)使程序模块化、通用化,便于阅读、交流和共享。 4) 便于分块调试。
参数传递大致可分为以下几种方法:
1) 传递数据:将数据通过工作寄存器R0~R7和累加器来传送。即主程序和子程序在交接处,通过工作寄存器或累加器存储要传递的参数。
2) 传送地址:数据存放在数据存储器中,参数传递时只通过R0、R1或DPTR传递数据所存放的地址。
3) 通过堆栈传递参数:在调用之前,先把要传送的参数压入堆栈,进入子程序之后,再将压入堆栈的参数弹出到工作寄存器或者其他内存单元。
设0、1、...、9存放在内部RAM的20H开始的存储区域内,对其进行平方运算,计算所得结果存放在R3、R2中。要求:平方运算编写成子程序SORT,主程序通过调用SORT并求和完成运算。参数的传递用累加器。
MAIN:
ORG 0000H JMP MAIN ORG 0100H
(此处自行填写程序:将0~9存入内部RAM的20H开始的存储区域内) MOV R0, #20H ;置数据指针 MOV R7, #10 ;置计数初值 MOV R3, #0 ;结果单元清零 MOV R2, #0
13