图1.10
4.2在线汇编技术
在进入Keil的调试环境后,如果发现程序有错,可以直接修改源程序,但是要使修改后的程序代码有效,必须先退出调试环境,重新编译连接后在进入调试,但如果只是需要对某些程序行进行测试,或仅需对原程序进行临时的修改,这样的过程就显得有些麻烦,为此Keil软件提供了在线汇编的能力,将光标定位于需要修改的程序行上,用菜单Debug->Inline Assambly…即可出现如图1.10所示的对话框。
图1.11
在Enter New后面的编辑框内直接输入要更改的程序语句,输入完后键入回车将自动指向下一条语句,可以继续修改,如果不再需要修改,可以点击右上角的关闭按钮关闭窗口。
4.3断点设置
程序调试时,一些程序行必须满足一定的条件才能被执行到(如程序中某变量达到一定的质、按键被按下、串口接收到数据、有中断产生等),这些条件往往是异步发生或难以预先设定的,这类问题使用单步调试方法是很难调试的,这时就要使用到程序调试中的另一种非常重要的方法——断点设置。设置好断点后可以全速运行程序,一旦运行遇到断点就会停止运行,此时可以观察有关变量的值,寄存器的值已确定问题所在。设置/移除断点的方法是将光标定位到需要设置断点的程序行,使用菜单Debug->Insert/Remove BreakPoint设置或移除断点,也可以用鼠标在该行双击实现相同的功能;Debug->Enable/Disable BreakPoint是开启或暂停光标所在行的断点功能;Debug->Disable All BreakPoint暂停所有断点;Debug->Kill All BreakPoint清除所有的断点设置。这些功能也可以用工具条中相应的快捷按钮进行设置。断点调试窗口如图1.11所示。
图1.12
断点设置工具条如图开启/关闭断点、关闭所有断点。
观测和修改存储器内容
所示。依次为设置/移除断点、取消所有断点、
(2)点击 命令,可以打开存储器观察窗口,在存储器观察窗口的
‘Address:’栏中输入D:30H(或 0x30)则显示片内 RAM30H 后的内容,如图1-12 所示。如果输入‘C:’表示显示代码存储器的内容,‘I:’表示显示内部间接寻址 RAM 的内容,‘X:’表示显示外部数据存储器中的内容。
(3)将光标移到 SJMP $语句行,点击 命令,在此行设置断点。 (4)接下来点击 命令,运行实验程序,当程序遇到断点后,程序停止运行,观察存储器中的内容,如图 1-13 所示,验证程序功能。
(5)如图1-12 所示,在命令行中输入‘E CHAR
D:30H=11H,22H,33H,44H,55H’后回车,便可以改变存储器中多个单元的内容,如图1-14 所示。
图1-13 运行程序后存储器窗口 图1-14 修改存储器内容
(6)修改存储器的内容的方法还有一个,就是在要修改的单元上点击鼠标右键,弹出快捷菜单,如图1-15 所示,选择‘Modify Memory at D:0x35’命令来修改 0x35 单元的内容,这样每次只能修改一个单元的内容。
图1-15 存储器修改单元
注意事项
1. 新建项目或源程序的路径名和文件名不能使用中文,项目和文件不能存放在桌面上。
2. 源程序编译出错时,请先检查
(1) 相应程序行中字母o和数码0是否用混了。
(2) 标点符号(尤其是“,”和“:”)是否是全角字符。
4. 不同实验内容的源程序(*.asm)不能加到同一个项目中,若已经加上,请单击“项目工作区”中相应文件的文件名,再按鼠标右键,选择“Remove File ?”,确认后即可从项目中移除相应文件。
实验一 汇编语言的应用及Keil C编译环境
一、实验目的
熟悉51指令系统,掌握程序设计方法。 二、实验内容
1、通过执行程序中的相关指令,将有关数据写入工作寄存器区、位寻址区、数据缓冲区和特殊功能寄存器区各存储单元
2、编写并调试一个排序子程序,其功能为用冒泡法将内存RAM中几个单字节无符号的正整数,按从小到大的次序重新排列。
三、实验步骤及参考程序:
1、编写程序,将有关数据写入工作寄存器区、位寻址区、数据缓冲区和特殊功能寄存器区各存储单元,并参考预备知识中有关内容对程序的执行结果进行检查。
参考程序A:工作寄存器区的数据传送 地址 机器码 源程序 ORG 0000H 0000H 78 11 MOV R0,#11H 0002H 79 22 MOV R1,#22H 0004H 7A 33 MOV R2,#33H 0006H 7B 44 MOV R3,#44H 75 D0 MOV PSW,#10H 0008H 10 000BH 78 55 MOV R0,#55H 000DH 79 66 MOV R1,#66H 000FH 7A 77 MOV R2,#77H 0011H 7B 88 MOV R3,#88H SJMP $ END 注释 ;表示程序从地址0000H存放 ;将立即数11H送到寄存器R0中 ;将立即数22H送到寄存器R1中 ;将立即数33H送到寄存器R2中 ;将立即数44H送到寄存器R3中 ;使工作寄存器工作于2区 ;将立即数55H送到寄存器R0中 ;将立即数66H送到寄存器R1中 ;将立即数77H送到寄存器R2中 ;将立即数88H送到寄存器R3中 ;程序结束 检查数据 ( H)=11H ( H)=22H ( H)=33H ( H)=44H ( H)=10H ( H)=55H ( H)=66H ( H)=77H ( H)=88H 参考程序B:位寻址区的数据传送 地址 0100H 0103H 0105H 0107H 0109H 010BH 010DH 010FH 0111H 0113H 0116H 0118H 011AH 011CH 机器码 75 20 F0 D2 00 D2 01 D2 02 D2 03 C2 04 C2 05 C2 06 C2 07 75 90 FF C2 90 D2 90 C2 91 D2 91 源程序 ORG 0000H MOV 20H,#0F0H SETB 00H SETB 01H SETB 02H SETB 03H CLR 04H CLR 05H CLR 06H CLR 07H MOV P1,#0FFH CLR 90H SETB 90H CLR 91H SETB 91H SJMP $ END 注释 检查数据 ;表示程序从地址0000H存放 ;将字节地址20H单元中的内容置(20H)= F0H ;将位地址00H单元中的内容置1 ( H)=1 ;将位地址01H单元中的内容置1 ( H)=1 ;将位地址02H单元中的内容置1 ( H)=1 ;将位地址03H单元中的内容置1 ( H)=1 ;将位地址04H单元中的内容置0 ( H)=0 ;将位地址05H单元中的内容置0 ( H)=0 ;将位地址06H单元中的内容置0 ( H)=0 ;将位地址07H单元中的内容置0 ( H)=0(20H)= ;将字节地址90H单元中的内容置FFH (90H)= ;将P1.0置0 ( H)=0 ;将P1.0置1 ( H)=1 ;将P1.1置0 ( H)=0 ;将P1.1置1 ( H)=1 ;程序结束 参考程序C:数据缓冲区和特殊功能寄存器区的数据传送(注意:本程序有两个错误,
也是我们编程常出现的小问题,请阅读执行debug时的出错代码,并参考上面两个程序进行修改)