论文部分内容阅读
摘要:本文浅谈了Debug在汇编语言程序上机调试中的基本步骤和方法,帮助学生如何利用Debug工具更好地学习汇编语言,对于汇编语言教学具有一定的参考价值。
关键词:汇编语言;Debug;调试;命令
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)09-11653-03
The Method of the Debug Debugging Assembly Language Procedure
JI Bo-jing
(Chizhou Institute, Chizhou 247100, China)
Abstract: This article discussed shallowly basic step and method of Debug in the assembly language procedure hands-on debugging, and help the students how to study the assembly language well by using the Debug tool. It has certain reference value regarding the assembly language teaching.
Key words: Assembly language; Debug; Debugging; Order
1 引言
汇编语言是一种介于计算机能直接识别、执行的机器语言和高级语言之间的程序设计语言。汇编语言最显著的特
点是它与机器硬件关系密切,与机器语言一一对应,可以编写出在“时空”两方面最有效率的程序,因此在系统软件开发、实时工业控制等场合中是必不可少的软件开发工具。现在大多数高校的计算机专业均将《汇编语言程序设计》作为必修课程,通过该课程的教学,有助于培养学生的程序设计方面的能力,同时可以让学生从根本上认识、理解计算机的工作原理,这对《接口技术》、《单片机》等后续课程的学习是非常有帮助的。但是在具体的教学过程中,尤其是在上机环节里学生普遍感到汇编语言程序难以调试,以至于不能很好的理解课堂上传授的理论知识,由此引发学生刚接触这门课程时学习兴趣不高。好在系统为我们提供了Debug工具,利用好这个调试工具将很大程度地帮助于我们调试好汇编语言程序,从而提高了学生的学习兴趣和教学效果。下面笔者结合教学实践就如何使用Debug来调试汇编语言程序这个问题谈谈自己的基本方法。
2 结合教学实践介绍Debug调试汇编语言程序的基本方法
2.1 调试程序前的准备工作
2.1.1 熟悉Debug工具中常用的命令的使用方法
Debug提供了一系列操作命令,具有很强的调试功能,涉及的内容也相当广。下面简要介绍在程序调试中使用的一些常用命令。
R--显示寄存器的内容 A--对助记符指令进行汇编
D--显示内存单元的内容 G--运行程序
U--对二进制指令代码进行反汇编 Q--退出Debug
E--修改存储区数据 T--单步执行程序
2.1.2 借助参考文件
利用汇编和连接过程中产生的.LST或.MAP文件信息,记下调试中某些关键变量、标号、子程序的地址,为便于调试中查看中间结果和设置断点位置。
2.1.3 制定调试步骤方案
多数同学在上机过程中,完成汇编语言源程序的编辑、汇编、连接以及进入Debug调试环境后,普遍感到束手无策,不知从何处开始调试,更无法得知程序的结果是否正确。面临这种问题,往往笔者在上机教学中告诉学生首先要回顾一下程序所要求实现的功能,其次借助.LST或.MAP文件信息分析出程序的已知条件 ,比如已知变量的值及存放的内存单元地址,进而可将已知变量数据所存储的示意图画在纸上,然后分析出程序运行的正确结果及所存放的具体地址。上述问题正确分析完后就可以制定出一个较具体的调试步骤方案。
2.2 调试过程的具体实施
2.2.1 启动Debug
在完成调试程序前的准备工作之后,就启动Debug程序,装入被调试程序进入调试环境。注意,进入Debug时一定要以完整的形式指定用户可执行程序文件名(完整路径\文件名.扩展名),装入被调试程序。
2.2.2 观察寄存器和数据单元的初始值
在装入用户程序后,先用R命令显示寄存器的初始值,通过CS和SS寄存器可以了解到程序代码段和堆栈段在内存中的分布位置;从IP可以知道第一条可执行指令在代码段中的起始地址;DS和ES中的值是相同的,注意它们并不是用户程序数据段的段基值,而是PSP的段基值。然后选择U命令或者查看连接过程中产生的.MAP文件来找出用户程序数据段的段值,如果用户想查看数据段中的内容,还必须提供变量的偏移地址,这时可以通过.LST文件或者画出变量存储示意图分析出数据段中定义的变量的偏移量。紧接着用D命令和已查到的数据段段基值、变量偏移地址来查看用户数据段中存储的内容。此时就可以对程序的各个功能段在内存中的存储分布情况有了具体的了解,便于后续的调试。
2.2.3 目标代码的反汇编
在运行程序之前,还须对要执行的代码段进行反汇编。只有这样才能确定待运行的程序段的起始地址、断点地址。
2.2.4 选用适当的运行程序命令,运行用户程序
Debug提供了G、T、P三个运行程序命令,这就要求我们要灵活的选用。比如,对执行顺序程序部分,通常使用G命令。对于要特别仔细查看的指令,可选用P命令或T命令,一般建议在单步执行时,选用P命令,在需要考察LOOP循环,进入子程序或软中断调用时,使用T命令进行跟踪运行。
2.2.5 断点的设置
在程序的各功能段调试中,可能包含有转移分支指令,往往需要对分支的原因、分支的正确性进行验证。这时就需要在G命令中加上断点参数。
2.2.6 观察运行结果
汇编语言源程序运行后,大多数情况下运行结果并不直观的显示在屏幕上,这时就可以选择D命令或者R命令来显示出存放在内存单元或寄存器中的运行结果。
如果用户希望像高级语言那样,程序运行结果可以直接显示在屏幕上,可以调用系统提供的DOS系统功能调用或者BIOS中断调用来显示。用户可以结合题目的要求和分析,对运行结果作出判断,从而可得知用户程序是否正确。
2.3 举例说明Debug在汇编语言中的调试方法
2.3.1 以下是该程序的功能要求和源程序清单:
;定义源字符串变量sstr的值为小写字母表,用程序将它复制到目标字符串dstr中。
datasegment
sstrdb’abcdefghijklmnopqrstuvwxyz’
dataends
extra segment
dstrdb 26 dup(?)
extra ends
codesegment
assume cs:code,ds:data,es:extra
start: mov ax,data
mov ds,ax
mov ax,extra
mov es,ax
lea si,sstr
lea di,dstr
mov cx,26
cld
repmovsb
movah,4ch; dos系统功能调用,标志源程序结束
int21h
code ends
endstart
2.3.2 具体调试过程
为了方便说明给该程序命名为“mycopy.asm”,首先在DOS环境下完成对该程序的编辑输入、汇编、连接,接着启动Debug将生成的mycopy.exe文件装入内存,输入R命令后,屏幕出现了各个寄存器的当前值,如下所示:
E:\MASM>debug mycopy.exe
-r
AX=0000BX=0000CX=005CDX=0000SP=0000BP=0000SI=0000DI=0000DS=13D3ES=13D3SS=13E3CS=13E7IP=0000 NV UP EI PL NZ NA PO NC
13E7:0000 B8E313MOVAX,13E3
可以查到当前代码段段基值是13E7H,堆栈段的段基值为13E3H,整个程序段所占内存大小存放在(BX,CX)中,为005CH个字节。
输入U命令后,屏幕出现了代码段在内存中的存放情况,如下所示:
-u cs:0
13E7:0000 B8E313MOVAX,13E3
13E7:0003 8ED8MOVDS,AX
13E7:0005 B8E513MOVAX,13E5
13E7:0008 8EC0MOVES,AX
13E7:000A 8D360000LEASI,[0000]
13E7:000E 8D3E0000LEADI,[0000]
13E7:0012 B91A00MOVCX,001A
13E7:0015 FCCLD
13E7:0016 F3REPZ
13E7:0017 A4 MOVSB
13E7:0018 B44C MOVAH,4C
13E7:001A CD21 INT21
13E7:001C EC IN AL,DX
13E7:001D 81EC9000 SUBSP,0090
可以查到数据段的段基值为13E3H,附加段段基值为13E5H,并可以找到待运行代码段的起始地址为13E7:0000,结束地址为13E7:001C。
经过分析后可以找到数据段中的小写字母表存放的首偏移地址是0,将要存放复制过来的小写字母表的首偏移地址也是0。这样就可以查看数据段中被复制的小写字母表在内存中存放的情况,选用D命令,如下所示:
-D 13E3:0 L1A
13E3:000061 62 63 64 65 66 67 68-69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
13E3:001071 72 73 74 75 76 77 78-79 7A qrstuvwxyz
可以看出屏幕显示三栏信息,右边栏显示的是数据段在内存中存放的信息,当前是小写字母表,中间栏显示的是这些小写字母在内存中存储的形式,均为十六进制,左边栏显示的是每一行的16个字节单元区域的首字节单元地址。
接下来选择G命令来运行程序,如下所示:
-G=13e7:0000001C
Program terminated normally
可以看出该程序的结果并没有直观显示出来,这时我们可以分析下该程序的功能,是将数据段中的小写字母表复制到附加段的存储区域,要想观察结果得用D命令去查看附加段所在内存单元的内容是否是小写字母表就可以了。如下所示:
-d 13e5:0 l1a
13E5:000061 62 63 64 65 66 67 68-69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
13E5:001071 72 73 74 75 76 77 78-79 7A qrstuvwxyz
结果已经显示在屏幕上了,可以看出附加段里有存放的小写字母表,可以判断该程序是正确的。
3结束语
“汇编语言程序设计”是一门实践性很强的学科,要求我们在学习理论知识的同时更重视上机环节的实践操作能力的培养,尤其要熟练地灵活使用Debug调试工具,以实验实践促进理论知识的深入理解,从而激发学生的学习兴趣,提高教学质量和教学效率,为学生的后续课程的学习打下扎实的基础。
参考文献:
[1] 沈美明. IBM——PC汇编语言程序设计[M].北京:清华大学出版社,1991.
[2] 王正智. 宏汇编语言程序设计[M].成都:电子科技大学出版社,2000.
[3] 罗省贤. 汇编语言程序设计教程[M].北京:电子工业出版社,2004.
[4] 杨季文. 80X86汇编语言程序设计教程[M].北京:清华大学出版社,1998.
关键词:汇编语言;Debug;调试;命令
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)09-11653-03
The Method of the Debug Debugging Assembly Language Procedure
JI Bo-jing
(Chizhou Institute, Chizhou 247100, China)
Abstract: This article discussed shallowly basic step and method of Debug in the assembly language procedure hands-on debugging, and help the students how to study the assembly language well by using the Debug tool. It has certain reference value regarding the assembly language teaching.
Key words: Assembly language; Debug; Debugging; Order
1 引言
汇编语言是一种介于计算机能直接识别、执行的机器语言和高级语言之间的程序设计语言。汇编语言最显著的特
点是它与机器硬件关系密切,与机器语言一一对应,可以编写出在“时空”两方面最有效率的程序,因此在系统软件开发、实时工业控制等场合中是必不可少的软件开发工具。现在大多数高校的计算机专业均将《汇编语言程序设计》作为必修课程,通过该课程的教学,有助于培养学生的程序设计方面的能力,同时可以让学生从根本上认识、理解计算机的工作原理,这对《接口技术》、《单片机》等后续课程的学习是非常有帮助的。但是在具体的教学过程中,尤其是在上机环节里学生普遍感到汇编语言程序难以调试,以至于不能很好的理解课堂上传授的理论知识,由此引发学生刚接触这门课程时学习兴趣不高。好在系统为我们提供了Debug工具,利用好这个调试工具将很大程度地帮助于我们调试好汇编语言程序,从而提高了学生的学习兴趣和教学效果。下面笔者结合教学实践就如何使用Debug来调试汇编语言程序这个问题谈谈自己的基本方法。
2 结合教学实践介绍Debug调试汇编语言程序的基本方法
2.1 调试程序前的准备工作
2.1.1 熟悉Debug工具中常用的命令的使用方法
Debug提供了一系列操作命令,具有很强的调试功能,涉及的内容也相当广。下面简要介绍在程序调试中使用的一些常用命令。
R--显示寄存器的内容 A--对助记符指令进行汇编
D--显示内存单元的内容 G--运行程序
U--对二进制指令代码进行反汇编 Q--退出Debug
E--修改存储区数据 T--单步执行程序
2.1.2 借助参考文件
利用汇编和连接过程中产生的.LST或.MAP文件信息,记下调试中某些关键变量、标号、子程序的地址,为便于调试中查看中间结果和设置断点位置。
2.1.3 制定调试步骤方案
多数同学在上机过程中,完成汇编语言源程序的编辑、汇编、连接以及进入Debug调试环境后,普遍感到束手无策,不知从何处开始调试,更无法得知程序的结果是否正确。面临这种问题,往往笔者在上机教学中告诉学生首先要回顾一下程序所要求实现的功能,其次借助.LST或.MAP文件信息分析出程序的已知条件 ,比如已知变量的值及存放的内存单元地址,进而可将已知变量数据所存储的示意图画在纸上,然后分析出程序运行的正确结果及所存放的具体地址。上述问题正确分析完后就可以制定出一个较具体的调试步骤方案。
2.2 调试过程的具体实施
2.2.1 启动Debug
在完成调试程序前的准备工作之后,就启动Debug程序,装入被调试程序进入调试环境。注意,进入Debug时一定要以完整的形式指定用户可执行程序文件名(完整路径\文件名.扩展名),装入被调试程序。
2.2.2 观察寄存器和数据单元的初始值
在装入用户程序后,先用R命令显示寄存器的初始值,通过CS和SS寄存器可以了解到程序代码段和堆栈段在内存中的分布位置;从IP可以知道第一条可执行指令在代码段中的起始地址;DS和ES中的值是相同的,注意它们并不是用户程序数据段的段基值,而是PSP的段基值。然后选择U命令或者查看连接过程中产生的.MAP文件来找出用户程序数据段的段值,如果用户想查看数据段中的内容,还必须提供变量的偏移地址,这时可以通过.LST文件或者画出变量存储示意图分析出数据段中定义的变量的偏移量。紧接着用D命令和已查到的数据段段基值、变量偏移地址来查看用户数据段中存储的内容。此时就可以对程序的各个功能段在内存中的存储分布情况有了具体的了解,便于后续的调试。
2.2.3 目标代码的反汇编
在运行程序之前,还须对要执行的代码段进行反汇编。只有这样才能确定待运行的程序段的起始地址、断点地址。
2.2.4 选用适当的运行程序命令,运行用户程序
Debug提供了G、T、P三个运行程序命令,这就要求我们要灵活的选用。比如,对执行顺序程序部分,通常使用G命令。对于要特别仔细查看的指令,可选用P命令或T命令,一般建议在单步执行时,选用P命令,在需要考察LOOP循环,进入子程序或软中断调用时,使用T命令进行跟踪运行。
2.2.5 断点的设置
在程序的各功能段调试中,可能包含有转移分支指令,往往需要对分支的原因、分支的正确性进行验证。这时就需要在G命令中加上断点参数。
2.2.6 观察运行结果
汇编语言源程序运行后,大多数情况下运行结果并不直观的显示在屏幕上,这时就可以选择D命令或者R命令来显示出存放在内存单元或寄存器中的运行结果。
如果用户希望像高级语言那样,程序运行结果可以直接显示在屏幕上,可以调用系统提供的DOS系统功能调用或者BIOS中断调用来显示。用户可以结合题目的要求和分析,对运行结果作出判断,从而可得知用户程序是否正确。
2.3 举例说明Debug在汇编语言中的调试方法
2.3.1 以下是该程序的功能要求和源程序清单:
;定义源字符串变量sstr的值为小写字母表,用程序将它复制到目标字符串dstr中。
datasegment
sstrdb’abcdefghijklmnopqrstuvwxyz’
dataends
extra segment
dstrdb 26 dup(?)
extra ends
codesegment
assume cs:code,ds:data,es:extra
start: mov ax,data
mov ds,ax
mov ax,extra
mov es,ax
lea si,sstr
lea di,dstr
mov cx,26
cld
repmovsb
movah,4ch; dos系统功能调用,标志源程序结束
int21h
code ends
endstart
2.3.2 具体调试过程
为了方便说明给该程序命名为“mycopy.asm”,首先在DOS环境下完成对该程序的编辑输入、汇编、连接,接着启动Debug将生成的mycopy.exe文件装入内存,输入R命令后,屏幕出现了各个寄存器的当前值,如下所示:
E:\MASM>debug mycopy.exe
-r
AX=0000BX=0000CX=005CDX=0000SP=0000BP=0000SI=0000DI=0000DS=13D3ES=13D3SS=13E3CS=13E7IP=0000 NV UP EI PL NZ NA PO NC
13E7:0000 B8E313MOVAX,13E3
可以查到当前代码段段基值是13E7H,堆栈段的段基值为13E3H,整个程序段所占内存大小存放在(BX,CX)中,为005CH个字节。
输入U命令后,屏幕出现了代码段在内存中的存放情况,如下所示:
-u cs:0
13E7:0000 B8E313MOVAX,13E3
13E7:0003 8ED8MOVDS,AX
13E7:0005 B8E513MOVAX,13E5
13E7:0008 8EC0MOVES,AX
13E7:000A 8D360000LEASI,[0000]
13E7:000E 8D3E0000LEADI,[0000]
13E7:0012 B91A00MOVCX,001A
13E7:0015 FCCLD
13E7:0016 F3REPZ
13E7:0017 A4 MOVSB
13E7:0018 B44C MOVAH,4C
13E7:001A CD21 INT21
13E7:001C EC IN AL,DX
13E7:001D 81EC9000 SUBSP,0090
可以查到数据段的段基值为13E3H,附加段段基值为13E5H,并可以找到待运行代码段的起始地址为13E7:0000,结束地址为13E7:001C。
经过分析后可以找到数据段中的小写字母表存放的首偏移地址是0,将要存放复制过来的小写字母表的首偏移地址也是0。这样就可以查看数据段中被复制的小写字母表在内存中存放的情况,选用D命令,如下所示:
-D 13E3:0 L1A
13E3:000061 62 63 64 65 66 67 68-69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
13E3:001071 72 73 74 75 76 77 78-79 7A qrstuvwxyz
可以看出屏幕显示三栏信息,右边栏显示的是数据段在内存中存放的信息,当前是小写字母表,中间栏显示的是这些小写字母在内存中存储的形式,均为十六进制,左边栏显示的是每一行的16个字节单元区域的首字节单元地址。
接下来选择G命令来运行程序,如下所示:
-G=13e7:0000001C
Program terminated normally
可以看出该程序的结果并没有直观显示出来,这时我们可以分析下该程序的功能,是将数据段中的小写字母表复制到附加段的存储区域,要想观察结果得用D命令去查看附加段所在内存单元的内容是否是小写字母表就可以了。如下所示:
-d 13e5:0 l1a
13E5:000061 62 63 64 65 66 67 68-69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
13E5:001071 72 73 74 75 76 77 78-79 7A qrstuvwxyz
结果已经显示在屏幕上了,可以看出附加段里有存放的小写字母表,可以判断该程序是正确的。
3结束语
“汇编语言程序设计”是一门实践性很强的学科,要求我们在学习理论知识的同时更重视上机环节的实践操作能力的培养,尤其要熟练地灵活使用Debug调试工具,以实验实践促进理论知识的深入理解,从而激发学生的学习兴趣,提高教学质量和教学效率,为学生的后续课程的学习打下扎实的基础。
参考文献:
[1] 沈美明. IBM——PC汇编语言程序设计[M].北京:清华大学出版社,1991.
[2] 王正智. 宏汇编语言程序设计[M].成都:电子科技大学出版社,2000.
[3] 罗省贤. 汇编语言程序设计教程[M].北京:电子工业出版社,2004.
[4] 杨季文. 80X86汇编语言程序设计教程[M].北京:清华大学出版社,1998.