实训2 程序规范化与调试能力.docx
《实训2 程序规范化与调试能力.docx》由会员分享,可在线阅读,更多相关《实训2 程序规范化与调试能力.docx(21页珍藏版)》请在冰豆网上搜索。
实训2程序规范化与调试能力
实训2程序规范化与调试能力
一、实训目的与要求
目的:
1、熟悉程序设计规范化原则。
2、掌握程序调试的基本方法。
要求:
1)体会规范化程序的优点。
6)掌握观察源程序汇编代码的方法。
2)熟悉程序排版规范化规则。
7)掌握观察和修改寄存器的方法。
3)熟悉程序注释规范化规则。
8)掌握观察和修改存储单元的方法。
4)熟悉程序设计的命名规则。
9)掌握单步调试程序的方法。
5)熟悉程序设计的可维护性原则。
10)掌握全速运行程序的方法。
二、相关知识与技能
1、复习C语言课本,了解编程规范化的知识。
2、回顾仿真环境的基本使用方法。
三、实训内容与步骤
A.程序规范化能力部分:
例2-1:
请同学们对比注释尝试解释下面程序
ORG0000H
LJMPSTART
//跳转的程序的开始ORG0030H//程序从0030H开始
START:
MOVDPTR,#40H
//把立即数40H送到DPTR
MOVR0,#2FH//把2FH送到R0
MOVA,@R0//把累加器A的内容给寄存器R7
MOVR7,A
INCR0
TRANS:
MOVA,@R0
//将以寄存器R0内容为地址的内存单元的内容给累加器A
MOVX@DPTR,A
INCR0//寄存器R0的内容加1
INCDPTR
DJNZR7,TRANS//减1不为0跳转指令,当寄存器R7为0时不跳转
SJMP$
END
从程序的排版规范、注释规范上对上述程序的评价:
实训1:
排版的规范
要求:
掌握排版规则
操作:
在KeilC软件中练习下列左边的源程序,并对照学习右边的规则。
ORG0000H
LJMPSTART
ORG0030H
用START:
MOVDPTR,#40H
TABMOVR0,#2FH
键MOVA,@R0
缩MOVR7,A
进INCR0
并TRANS:
MOVA,@R0
对MOVX@DPTR,A
齐INCR0
INCDPTR
DJNZR7,TRANS
SJMP$
END
规则1:
程序块使用缩进方式,函数和标号使用空格缩进,程序段混合使用TAB和空格缩进。
缩进的目的是使程序结构清晰,便于阅读和理解。
规则2:
在指令和操作数之间的,使用空格进行间隔,采用这种松散方式编写代码的目的是使代码更加清晰。
规则3:
一行最多写一条语句。
规则4:
变量定义时,保持对齐。
便于阅读和检查内存的使用情况
在汇编语言中并不是非常明显的体现排版的规范,但在以后将要用的到C语言编程中,排版规范就体现的非常明显,下面是一段C语言小程序:
1、用TAB键缩进,层次关系鲜明,同一层次的对齐,便于阅读理解。
2、一行写一个语句。
main()
{
inta=4,b=3,c=2,d=1;
if(a>b)
{
if(b>c)
{
if(c>d)
{
d=0;
c=0;
b=0;
a=0;
}
}
}
}
在下面的横线上用汇编或C语言书写一段排版规范的小程序。
实训2:
注释的规范
要求:
掌握注释规则,
操作:
在KeilC软件中为实训1的程序添加上注释(编译器用“//”或“/*…*/”来区分是否为注释,切勿在程序代码部分输入任何中文状态字符,否则将导致编译时出错,并且这种错误通常很难发现。
)。
规则1:
程序在必要的地方必须有注释,注释要准确、易懂、简洁。
规则2:
注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
规则3:
注释必须要有含金量,含金量很重要。
在下面右边的横线上填上注释:
ORG0000H
//跳转到标号为START处运行程序(注释在上方,应与上面代码用空行隔开)
LJMPSTART
ORG0030H//程序从ROM的0030H单元开始存放(注释在右方)
START:
MOVDPTR,#40H
MOVR0,#2FH/*把2FH存放到寄存器R0中(注释在右方)*/
MOVA,@R0
MOVR7,A/*把累计器A的内容给寄存器R7(注释在右方)*/
INCR0
TRANS:
MOVA,@R0//
MOVX@DPTR,A
INCR0//
INCDPTR
DJNZR7,TRANS/**/
SJMP$
END//程序结束(注释在右方)
对于注释的位置在规则中给出两种,但是在使用中要养成个人习惯,凭个人喜好只使用一种,有助于在编写程序时注释的统一。
注释的含金量:
对程序阅读者理解语句起到关键性的作用。
例如如下注释意义不大:
MOVDXCE1COUNTER,#00H//将DXCE1COUNTER赋值为0
而如下的注释则给出了额外有用的信息:
JNZPcComm_Err//假如校验出错
查看在上面横线上填写的注释,是否含金量较高?
实训3:
命名规范
要求:
掌握命名规则,形成个人独特的规范的命名方式
操作:
在KeilC中练习变量和函数的命名
形成缩写的几种技术:
1)去掉所有的不在词头的元音字母。
如screen写成scrn,primtive写成prmv。
2)使用每个单词的头一个或几个字母。
如ChannelActivation写成ChanActiv,
ReleaseIndication写成RelInd。
3)使用变量名中每个有典型意义的单词。
如CountofFailure写成FailCnt。
4)去掉无用的单词后缀ing,ed等。
如PagingRequest写成PagReq。
5)使用标准的或惯用的缩写形式(包括协议文件中出现的缩写形式)。
规则1:
变量命名约定:
<前缀>+主体//注释
变量命名要考虑简单、直观、不易混淆。
前缀是可选项,表示变量类型,由于汇编中变量多是单字节变量,所以单字节变
量可以不加前缀,对于bit和双字节型变量,使用小写的b和d作为前缀表示。
主体是必选项,可多个单词(或缩写)合在一起,每个单词首字母大写,其余部分
小写。
例如:
COMEQU20H//指令寄存器
DATEQU21H//数据寄存器
CW_AddEQU0000H//指令口写地址
CR_AddEQU0002H//指令口读地址
DW_AddEQU0001H//数据口写地址
DR_AddEQU0003H//数据口读地址
规则2:
函数的命名:
单词首字母为大写,其余均为小写。
函数名应以一个动词开头,即函数名应类一个动词断语或祈使句。
例如:
Test_Protect,Check_EEPROM,Init_Para
规则3:
关键词不可用作变量名、函数名
例如:
MOVP1ORLXRLCLR等等。
翻阅书本了解其余的所有关键词。
实训4:
可维护性
要求:
掌握函数的使用、宏定义的使用
操作:
将以下带子函数调用的程序在KeilC软件中进行断点加单步调试,查看程序调用子函数的过程。
1、宏定义使用:
了解宏定义的使用,在汇编语言中宏定义是用EQU或=来实现的,当在一个函数中要使用一个常量或一个端口时我们需要使用宏定义以方便程序的修改和移植。
例如:
在程序中需要用到一个常量10,我们在程序首用=来宏定义这个常量:
LEN=10
ORG0000H
START:
MOVA,LEN
……
MOVP1,LEN
……
MOVP2,LEN
……
END
ORG0000H
START:
MOVA,10
……
MOVP1,10
……
MOVP2,10
MOVA,10
……
END
在右边的程序中我们要把常量10改成15时,需要把程序中的每一处10都修改一遍。
在左边的程序中当需要把常量10更改成15时不需要在程序中的每处都修改,只需修改宏定义LEN=15就可以,这样很显眼的体现的宏定义的好处。
端口宏定义用法同常量一样,用关键词EQU来定义,例如:
COMEQUP1
ORG0000H
START:
MOVCOM,A
……
MOVCOM,67H
……
MOVCOM,A
……
END
ORG0000H
START:
MOVP1,A
……
MOVP1,67H
……
MOVP1,A
MOVP1,78H
……
END
同样当需要把端口P1改成P2时,左边的程序只要更改宏定义处即可,而右边的程序需要修改程序所有地方的P1。
2、子程序(函数)使用:
规则1:
每个子程序完成单一的功能,不设计多用途面面俱到的子程序。
多功能集于一身的子程序,很可能使子程序的理解、测试、维护等变得困难。
使子程序功能明确化,增加程序可读性,亦可方便维护、测试。
规则2:
每个函数的源程序行数原则上应该少于200行。
对于消息分流处理函数,完成的功能统一,但由于消息的种类多,可能超过200行的限制,不属于违反规定。
有重复代码的程序:
ORG0000H
START:
MOVP1,#0FFH
MOVP3,#0FFH
MOVSP,#30H
MOVR7,#08H
MOVA,P3//读按键
CPLA
MOVP1,A
MOVR2,#50
L0:
MOVR3,#10
L1:
MOVR4,#125
L2:
NOP
NOP
DJNZR4,L2
DJNZR3,L1
DJNZR2,L0
MOVP1,#0FFH
MOVR2,#50
L3:
MOVR3,#10
L4:
MOVR4,#125
L5:
NOP
NOP
DJNZR4,L5
DJNZR3,L4
DJNZR2,L3
LJMPSTART
END
把重复代码做成子程序进行调用:
ORG0000H
START:
MOVP1,#0FFH
MOVP3,#0FFH
MOVSP,#30H
MOVR7,#08H
MOVA,P3//读按键
CPLA
MOVP1,A
ACALLDELY
MOVP1,#0FFH
ACALLDELY
LJMPSTART
DELY:
MOVR2,#50
L0:
MOVR3,#10
L1:
MOVR4,#125
L2:
NOP
NOP
DJNZR4,L2
DJNZR3,L1
DJNZR2,L0
RET
END
B.程序调试能力部分:
实例5:
假定数据串存放在内部RAM从30H开始的连续单元中,数据串长度存放在累加器A中,传送的目的区起址是内部RAM从40H开始的连续单元。
(具体数据在调试中设定)
内部RAM
外部RAM
35H
0045H
34H
9AH
0044H
33H
78H
0043H
32H
56H
0042H
31H
34H
0041H
30H
12H
0040H
2FH
003FH
地址
内容
内容
地址
图2-1
源程序清单:
行号
源程序
给出程序注释
1
ORG0000H
2
START:
MOVDPTR,#40H
;
3
MOVR0,#30H
;
4
MOVR7,A
;
5
TRANS:
MOVA,@R0
;
6
MOVX@DPTR,A
;
7
INCR0
;
8
INCDPTR
;
9
DJNZR7,TRANS
;
10
SJMP$
;
11
END
操作要求:
建立工程并输入源程序、对工程进行编译并创建调试目标、进入调试状态。
1、进入调试状态后,系统自动打开反汇编窗口(图2-2),如果看不到,可由【View】→【DisassemblyWindow】打开,观察源程序的汇编代码,将5-9行内容填入下表1-1内
行号
源代码
汇编代码
机器码
5
TRANS:
MOVA,@R0
6
MOVX@DPTR,A
7
INCR0
8
INCDPTR
9
DJNZR7,TRANS
表1-1
图2-2
2、由左侧寄存器窗口,双击累加器A旁的值至蓝色可编辑状态(图1-13),将累加器A的值由00H修改为05H(循环次数5次)。
图2-3
3、观察并修改内部RAM30H~34H单元的值为12H,34H,56H,78H,9AH。
1由【View】→【MemoryWindow】,打开内存窗口
2在【Address】栏输入D:
30H并按回车(图2-4),表示从内部RAM的30H开始显示调试值(从左到右地址依次递增)。
图2-4
3鼠标右键点击内存窗口的30H位置,在弹出菜单中选择【ModifyMemoryatD:
0x30】(图2-5)。
图2-5
4在弹出对话框中输入值12H(图2-6),并点击【OK】,表示修改内部RAM30H内的值为12H。
图2-6
5重复步骤4,将31H~34H单元的数据修改为源数据区数据值(图2-7)。
图2-7
小提示:
1、在修改内存单元数据时,也可以一次修改多个单元的数据。
方法是在输入数据时多个数据间用逗号隔开。
例如要修改30H~34H单元的数据为源数据区数据,可以在30H单元修改数据时输入“12H,34H,56H,78H,9AH”。
2、输入数据时的后缀H不能省略,代表16进制数,也可以用0x开始的前缀代替。
例如:
12H可以写成0x12
4、观察外部RAM内容
1由【View】→【MemoryWindow】,打开内存窗口;
2在【Address】栏输入x:
0040H并按回车(图2-8),从左到右地址依次递增;
图2-8
小提示:
1、地址栏输入不同的字母代表不同的存储空间,具体含义如下:
D:
表示内部RAM空间
X:
表示外部RAM空间
C:
表示程序存储器ROM空间
2、在内存窗口中可以通过选择4个不同的页面来查看不同的存储空间。
如:
Memory1#或Memory2#或Memory3#或Memory4#
5、单步方式运行程序
1)【Debug】→【Step】(F10)开始单步运行到PC指针指向第5条语句,观察指针R0、DPTR、计数长度R7和累加器A的内容并纪录于表1-2第一行中。
寄存器名称
R0
R7
DPTR
A
1)寄存器内容
2)寄存器内容
表1-2
2)单步运行行号5-9-5语句一遍,关注指针R0、DPTR、计数长度R7和累加器A的内容变化并纪录于表1-2第二行中。
6、全速运行,按【Debug】→【Go】(F5),查看外部RAM单元内容并纪录于表1-3,以确认程序是否完成了规定功能。
外部RAM单元
0040H
0041H
0042H
0043H
0044H
外部RAM中内容
表1-3
小提示:
StepInto【F10】和StepOver【F11】都是单步调试命令,但二者是有区别的。
当执行的指令是调用子程序或调用函数时,StepInto会进入子程序或函数内部跟踪执行,但StepOver只把它当做一条指令执行,不进行子程序或函数的内部跟踪执行。
四、实训总结与拓展
总结:
1、程序规范化中使用TAB键进行快速对齐。
2、使用有意义的标号。
3、不能使用系统保留字作为标号。
4、重复使用的程序段尽量使用子程序调用。
5、宏定义能够减轻程序的维护工作。
拓展:
编写一个规范化的带函数调用的汇编语言小程序并加上注释。
实训2程序规范化与调试能力考核表
序号
考核内容
成绩
时间
考核人
备注
1
排版的规范和技巧
2
注释规范和作用
3
宏定义的使用和作用
4
观察汇编代码
5
观察和修改寄存器
6
观察和修改存储单元
7
单步调试和全速运行