汇编语言上机操作及程序调试的方法.docx
《汇编语言上机操作及程序调试的方法.docx》由会员分享,可在线阅读,更多相关《汇编语言上机操作及程序调试的方法.docx(16页珍藏版)》请在冰豆网上搜索。
汇编语言上机操作及程序调试的方法
汇编语言上机操作及程序调试的方法
第一节在IBM-PC机上运行汇编源程序所必备的软件
为了在IBM-PC机上运行汇编源程序,机器上必须有DOS操作系统环境,DOS系统盘上应有下列文件:
EDIT文件编辑程序
MASM宏汇编程序
CREF交叉引用文件处理程序
LINK链接程序
LIB库管理程序
DEBUG调试程序
第二节在IBM-PC机上运行汇编源程序的步骤
当用户编制好汇编语言源程序之后,要在机器上运行,必须经过以下几个步骤:
1.用EDIT命令建立与修改汇编源程序文件(ASM文件)
源程序就是用汇编语言的语句编写的程序,它不能被机器识别。
源程序必须以ASM为附加文件名。
至于EDIT的使用方法可以查阅手册。
2.用MASM命令汇编源文件以产生相应的目标文件(OBJ文件)
源程序建立以后,必须经过汇编,转换成用二进制代码表示的目标文件,机器才可运行。
汇编是通过调用PC—DOS下的宏汇编程序MASM实现的。
汇编过程中,汇编程序对源文件进行二次扫描,如果源程序中有语法错误,则汇编过程结束后,汇编程序会指出源程序中的错误,这时,用户可以再用编辑程序来修改源程序中的错误,最后,得到没有语法错误的OBJ文件。
3.用LINK命令连接目标文件以产生可执行文件(EXE文件)
由于汇编之后所得到的目标代码的存放地址并不是可执行的绝对地址,而是浮动的相对地址,因而,必须经过连接,把程序的各个模块连接在一起,或把要调用的子程序与主程序连接在一起,把相对地址变成绝对地址,形成可执行的文件。
连接是由调用PC—DOS下的LINK程序来实现的。
4.调试、运行可执行文件。
经过以上过程,在盘上有了可执行文件,则可在DOS提示符下,直接打入文件名(不用扩展名),就可以把执行文件从盘上装入内存,且立即执行此程序。
然而通常一个较复杂、较长的汇编语言源程序,希望一点错误也没有的可能性是很小的,这样就需要调用PC—DOS支持下的DEBUG程序,来调试我们的目标程序。
被调试程序在DEBUG的管理下,可以单步执行程序,也可以设置断点,可以显示和修改CPU内部寄存器和标志位的内容等,这样就便于寻找程序中的错误。
在发现了错误以后,通常还要重复上述的编辑、汇编,连接和调试程序的全过程,直至程序运行正确为止。
已调试的目标程序,任何时候都可在PCDOS下,通过打入文件名即可运行它。
上机过程示意图如下:
为了便于操作,下面将上机操作全过程中的主要部分分别加以介绍,编辑程序因为使用普遍,在此不做介绍。
第三节宏汇编程序
经过编辑命令建立和修改后存盘的汇编语言源程序(扩展名为.ASM),要在机器上运行,必须先由汇编程序把它汇编为机器码的目标程序。
经过IBM汇编程序汇编后的程序在盘上建立三个文件:
一个是扩展名为.OBJ的目标程序。
在此程序中,操作码部分已变为机器码,但操作数地址只是一个可浮动的相对地址,而不是内存中的绝对地址。
第二个是扩展名为.LST的汇编列表文件,它把源程序(包括注释)和汇编后的目标程序都制表,可以打印出来供检查用。
第三个是扩展名为.CRF的符号交叉列表文件,可以对符号进行前后对照。
在汇编时,汇编程序对要不要建立这些文件,有如下提示:
例如对exam.asm文件进行汇编:
在DOS状态下,打入MASM调用宏汇编程序,屏幕显示与操作如下:
C>MASM↙
此时,屏幕上出现如下信息:
TheIBMPersonalComporterMACROAssemble,
1.00(C)Copyright。
IBMCorp1981.
Sourcefilename[.ASM]:
exam↙
Objectfilename[exam.Obj]:
↙
SourceListing[Nul.1st]:
exam↙
Crossreference[Nul.crf]:
exam↙
WarningSeveres
ErrorsErrors
00
从上面操作过程中可以见到,汇编程序的输入文件就是:
用户编写的源程序,它必须以ASM为文件扩展名,在汇编调入后,先显示版本号,然后出现第一行提示,询问要汇编的源文件名。
用户输入文件名,则出现第二个提示,询问目标程序的文件名,括号内的为机器规定默认的(default)文件名,通常直接按回车,表示采用默认文件名,接着出现第三个提示,问是否要建立可打印文件,若要,打入文件名,若不要,可直接回车。
最后出现第四个提示,询问是否要建立交叉索引文件,若需要则打入文件名,若不要直接回车。
在回答了第四个询问后,汇编程序就对源程序进行汇编。
汇编过程结束时,如果程序有错误会给出源程序的警告性错误(warningerrors)和严重错误(severserrors)。
前者指出一般性错误,后者指出语法性错误。
当存在这两类错误时,屏幕上除指出错误个数外,还给出错误信息代号。
程序员可以通过查代码手册弄清楚错误的性质。
如果汇编过程中,发现有错误,则程序员应该重新用编辑命令修改错误,再进行汇编,最终直到汇编正确通过。
要指出的是汇编过程只能指出源程序中的语法错误,并不能指出算法错误和其他错误。
注意:
汇编后建立的.CRF文件是不能单独使用的,若需要了解源程序中的符号(包括变量)在定义和引用时的情况,还要调用CREF文件对CRF文件进行处理,生成.REF文件后,才能打印(或显示)输出.其过程如下:
C>CREF↙
Creffilename[.CRF]:
exam↙
Listfilename[exam.REF]:
↙
在DOS状态下,打入CREF,就会调入交叉引用文件处理程序CREF。
CREF运行时,首先询问要处理的文件名。
在键入文件名后,出现第二个提示,询问.REF文件名,可用回车承认默认的.REF文件名。
于是就建立了一个扩展名为.REF的文件,然后返回DOS状态。
在DOS状态,用TYPE命令打印此文件,得如下显示信息:
SymbolCross_Reference(#isdefinition)Cref_1
BUF***********8#16
CODE**********12#1321
DATA**********7#111314
STACK**********1#613
START**********14#22
其中,有#号者是此符号被定义时的语句行号,后面是引用此符号的语句行号。
第四节连接程序(Link)
由汇编程序建立的目标码文件必须经过连接以后,才能成为可执行文件。
连接程序并不是专为汇编语言设计的。
利用它可以把若干个模块连接在一起,这些模块可以是汇编程序产生的目标码文件,也可以是其它高级语言编译程序产生的目标文件。
在连接过程中,又建立了几个文件。
具体操作如下(以exam.obj进行连接为例):
C>LINK↙
此时,屏幕上出现如下信息:
IBM5552multistationLinker2.00(C)CopyrightIBMCorp.1985
Corp.1985
Objectmodules[.OBJ]exam↙
RunFile[exam.EXE]:
↙
ListFile[NUL.MAP]:
exam↙
Libraries[.LIB]:
↙
Warning:
NOSTACKSegment
首先询问要连接的目标文件,操作员键入文件名作为回答(此处是exam)。
如果有多个要连接的目标文件,应一次键入。
各目标文件名之间用“+”号隔开。
第二个提示询问要产生的可执行文件的文件名,一般直接回车就采用了括号内规定的默认文件名。
第三个提示询问是否要建立地址分配文件。
键入文件名再回车表示要建立,直接按回车键表示不要建立。
最后询问是否用到库文件,如果没有库文件,则直接键入回车即可(如果用户用到库文件,则键入库文件名。
建立库文件的方法见第五节)。
回答以上问题后,连接程序便开始进行连接。
若连接过程有错,则显示错误信息。
若有错误就要重新调用编辑程序修改源文件,然后重新汇编、连接,直至无错。
LINK过程产生两个输出文件,一个是扩展名为EXE的执行文件.产生此文件当然是LINK过程的主要目的,另一个是扩展名为MAP列表分配文件,有人也称它为映象文件,它给出每个段在内存中的分配情况。
比如某个列表分配文件为如下内容:
C>TYPEexam.Map↙
Warning:
NoSTACKSegment
StartStopLengthName
00000H0015H0016HCODE
00020H0045H0026HDATA
00050H0061H0012HEXTRA
ProgrameEntrypointat0002:
0000
由上面看出,变量CODE的起始地址是0000H,结束地址是0015H,字节数是16H,以此类推。
另外从LINK过程提示信息中,可看到最后给出一个“无堆栈段”的警告性错误,这并不影响程序的执行。
当源程序中设置了堆栈段,则无此提示信息。
第五节子程序库的建立方法
在处理比较复杂的问题时,往往需要把某些经常被反复调用的子程序汇编成目标模块,集合在一起组成一个“子程序库”(.LIB),以方便调用。
建立子程序库是调用DOS的库管理程序LIB来实现的。
库管理程序LIB的启动方式分为提问方式、命令方式、文件方式三种,此处仅介绍提问方式。
在DOS状态,键入“LIB↙”之后,DOS把LIB装入主存并向用户提问,用户根据要求键入相应的回答。
LIB的提问信息及其回答如表1所示,回答时可用的命令字符如表2所示。
表1LIB的提示信息及回答
提示信息
回答
Libraryname:
Operation:
Listfile:
欲进行操作的库名(缺省文件扩展名为.LIB)
命令字符及模块名或目标文件名
交叉参考列表文件名(缺省:
NUL,无交叉参考列表文件)
表2库管理命令字符
命令字符
功能
+
-
*
;
&
CTRL_C
把目标代码文件作为最后一个模块加入库中
从库中删除一个模块
从库中取出模块,写入目标文件中(库中仍保留)
剩下的提示取缺省值
提示信息在一行内回答不下时,键入此字符将另起一行
终止库管理操作
下面举例说明子程序库的建立方法.
建立一子程序库WAN.LIB,将子模块QUEUE、F10T2、F2T10放入该库中,其操作步骤如下:
⑴建立它们的源文件QUEUE.ASM、F10T2.ASM、F2T10.ASM。
⑵将这三个源文件模块分别汇编,生成目标文件QUEUE.OBJ、F10T2.OBJ、F2T10.OBJ。
⑶调用库管理程序LIB建立子程序库WAN.LIB,并将三个目标文件加入库中,既可逐个加入,也可一次加入。
如果逐个加入,可用以下方法
(一):
C>LIB↙
Microsoft(R)LibraryManagerVersion3.04
Copyright(C)MicrosoftCorp1983,1984,1985,1986.
Allrightsreserved.
Libraryname:
WAN↙
Librarydoesnotexist.Create?
Y↙
Operations:
+QUEUE↙
Listfile:
↙
C>LIB↙
Microsoft(R)LibraryManagerVersion3.04
Copyright(C)MicrosoftCorp1983,1984,1985,1986.
Allrightsreserved.
Libraryname:
WAN↙
Librarydoesnotexist.Create?
Y↙
Operations:
+F10T2↙
Listfile:
↙
C>LIB↙
Microsoft(R)LibraryManagerVersion3.04
Copyright(C)MicrosoftCorp1983,1984,1985,1986.
Allrightsreserved.
Libraryname:
WAN↙
Librarydoesnotexist.Create?
Y↙
Operations:
+F2T10↙
Listfile:
↙
如果一次加入,可用如下方法
(二):
C>LIB↙
Microsoft(R)LibraryManagerVersion3.04
Copyright(C)MicrosoftCorp1983,1984,1985,1986.
Allrightsreserved.
Libraryname:
WAN↙
Librarydoesnotexist.Create?
Y↙
Operations:
+QUEUE+F10T2+F2T10↙
Listfile:
↙
库文件建立以后,库中的子程序可以方便地被其它程序调用。
例如,当子程序模块QUEUE、F10T2、F2T10入子程序库WAN.LIB之后,主模块MAIN.ASM汇编后可按如下方式连接(假定主模块的目标文件为MAIN.OBJ,且主模块中调用子模块QUEUE、F10T2及F2T10):
C>LINK↙
Microsoft8086ObjectLinker
Version2.44(C)CopyrightMicrosoftCorp1983
ObjectModules[.OBJ]:
MAIN↙
RunFile[MAIN.EXE]:
↙
ListFile[NUL.MAP]:
↙
Libraries[.LIB]:
WAN↙
连接后得到可执行文件MAIN.EXE。
第六节DEBUG程序调用及汇编语言程序调试方法
调试程序DEBUG是DOS支持的又一种系统软件,主要用于汇编语言程序的调试。
汇编和连接过程只能查出源程序的语法错误,不能查出功能上的错误和程序不完善的地方。
DEBUG程序为用户提供多种命令,大致有:
显示和修改寄存器和存贮单元的内容;执行程序中任意一段或一条指令;汇编单条源语句和反汇编机器码指令;查找字符代码;端口的输入和输出;文件装入内存和写入磁盘等。
用户利用这些命令可以查出任何程序功能上的错误。
下面说明DEBUG程序的启动方法和主要命令意义。
一、DEBUG程序的启动
DEBUG程序有两种启动方法。
DEBUG程序是在DOS盘上的一个独立的可执行程序(扩展名为.COM),所以,DEBUG程序的第一种启动方法就是把它看作和一般的可执行程序一样,只要打入DEBUG和回车键,就可以把它装入内存。
但是这样启动只把DEBUG程序本身装入内存并进入等待DEBUG命令状态,还没有把要调试的程序装入内存。
第二种启动DEBUG的程序的方法是一次相继装入DEBUG程序和要调试的程序。
打入的命令格式如下:
DEBUG[d:
][path]filename[.ext][parml]Lparm2]
其中的Filename是要调试程序的文件名,可选项[d:
][path]和[.ext]分别是要调试程序的所在盘符、路径和扩展名。
可选项[parml]和[parm2]是DEBUG程序为要调试程序准备的参数(一般不用)。
例进入DEBUG程序并装入要调试程序,要调试程序在A驱动器中。
其操作如下:
C>DEBUGA:
ABC.EXE(进入DEBUG,并装配ABC.EXE)
此时屏幕上出现一个短线,这表示可以使用DEBUG命令了。
二、调试命令
在说明每个命令之前,先说明一些共同信息:
■DEBUG命令都是以一个英文字母开头,后面跟一个或多个参数。
■命令字母和参数可用大写或小写或混合形式。
■命令字母和参数中,相邻两个十六进制之间必须用逗号或空格分开.其它各部分之间有无空格或逗号都可以。
■执行任何命令期间都可用Ctrl+Break键方法结束命令的执行。
■打入命令字母和参数后必须打入回车键才能使命令有效。
■如果执行某种命令期间在显示器或打印机上的很长的输出,可以按Ctrl+Numlock键暂停继续显示,使显示屏幕停下来供观察。
再按任何其它键,则继续显示输出。
■在DEBUG程序状态下,控制键和DOS支持的编辑键继续有效。
■如果输入的命令有错误,将显示出来。
例如:
dcs:
100cs:
110
error
这说明d命令的第二个address参数格式不对,它只能包括偏移地址部分,不能再有段地址部分。
它发现S不是十六进制数字符。
■DEBUG程序状态光标提示符为“-”。
下面按命令功能相近关系分组说明几个主要命令功能和使用的方法:
(一)显示和修改寄存器或存贮单元的有关命令
1.R(Register)命令
R命令有三种功能:
●显示单个寄存器内容并等待修改这个寄存器内容;
●显示CPU内部的所有寄存器的内容和全部标志位的状态;
●显示和修改所有标志位的状态。
⑴显示和修改单个寄存器内容命令
命令格式:
R[寄存器名]
说明:
显示单个寄存器内容。
R之后输入寄存器名符。
例如命令
-RAX↙
将显示出AX的内容和在下一行显示出冒号。
AXF1E4
:
-
上面的F1E4是AX的当前内容。
如果在冒号后打入要修改的内容,然后打回车键,这时AX即修改为新值;如果不输入新值只打回车键,则不改变原值。
⑵显示CPU内部的所有寄存器的内容和全部标志位的状态命令
命令格式:
R
说明:
显示所有寄存器和标志位值。
例如:
-R↙
系统响应给出格式如(值是假设的):
AX=0E00BX=00FFCX=0007DX=01FFSP=0390BP=0000SI=0050DI=0000DS=04BAES=04BASS=04BACS=04BAIP=01lANVUPDINGNZACPENC
04BA:
0HACD211NT21
前几行显示的是寄存器内容和8个状态标志位的状态,最后一行显示是下面将要执行的指令地址,它对应的机器码和汇编语句形式。
8位状态标志位的状态不是以0或1的形式显示的,而是用两个字母显示的。
字母和状态对应关系如表所示:
标志位名
为1对应符
为0对应符
OF(溢出标志)
OV
NV
DF(方向标志)
DN
UP
IF(中断标志)
EI
DI
SF(符号标志)
NG
PL
ZF(零标志)
ZR
NZ
AF(辅助进位)
AC
NA
PF(奇偶标志)
PE
PO
CF(进位标志)
CY
NC
⑶显示和修改标志位状态的命令
命令格式:
RF
系统响应是显示8个状态位。
例如:
OVDNEINGZRACPECY_(最后为光标位置)如果打入回车键,将不改变标志位的状态;也可以打入一个或多个新的状态符,重新设置其状态。
输入时各标志的次序无关,输入的各个标志之间可以没有空格。
如从光标位置开始打入:
PONZDINV
将改变第一、三、五、七个状态位的值。
2.D(Dump)命令
用途:
显示某个存储区的内容。
格式:
D[address]或D[range]
存储单元的内容用两种方式显示:
—种是每一个存储单元的内容(每一字节)用两位16进制数显示;另一种是用相应的ASCII字符显示,句号(.。
?
)表示不可显示的字符。
●如果取命令格式:
D
后面无地址或范围参数,将从前次命令显示后的下一个单元开始显示40H字节或80H字节的内容。
●如果取命令格式:
D[range]
则显示指定地址范围各单元的内容。
3.E(Enter)命令’
用途:
显示和修改存贮单元的内容。
格式1:
E[address][list]
将内容表包括的数值和字符串的ASCII码依次置入从指定地址开始的存贮单元。
例如:
EDS:
100F3“XYZ”8D
从内存单元DS:
100H至DS:
104H的5个单元中依次置入F3H(1个单元),XYZ的ASCII码(3个单元)和8DH(1个单元)。
格式2:
E[address]
显示指定地址单元的内容,并等待输入新的值。
输入新的值过程如下:
输入一个字节的十六进制数,以替换原单元中的内容,然后采取下列三种操作的一种。
(1)按空格键,则上一个替换要求完成,且显示出下一个单元的地址和原有的内容。
如果想改变它,可直接输入要修改的值,再按空格键,……,这样,就可以连续地进行修改。
若某一单元的内容不需要修改,可直接按空格键。
(2)按“—”号键,将在下一行显示前一单元的地址和内容。
如果想改变它,可直接输入要修改的值,然后再按“—”,则又显示前一单元的地址和内容,……,这样就可连续地进行反向修改。
若所示的前一单元的内容不需要修改,可直接按“—”键。
(3)按回车键将结束E命令。
命令参数中[地址]如果不指明段地址,则默认段地址为DS。
4.F(File)命令
用途:
在指定的存贮地址范围内置入内容表给出的数值或字符代码。
格式:
F[range][list]
说明:
如果list包含的字节少于range包括的单元数,则把list的字节重复置入指定的地址区,直到指定的范围都置入新值为止。
如果list包含的字节数多于range包括的单元数,则多出的字节被忽略。
如果range参数中不指明段地址,则默认段地址为DS。
例如:
F4BA:
100L5F3'XYZ'8D
则从04BA:
100至04BA:
104的5个单元依次装入F358595A8D。
(二)汇编与反汇编命令
1.A(Assemed)命令
用途:
先显示汇编的内存地址,等待用户输入一条助记符指令。
用户输入指令并按回车后,DEBUG将把这条指令对应的机器码顺序存放在指定的内存单元中,并提示下一地址,等待用户继续输入下一条指令。
若直接按回车,则退出A命令;若在输入指令时语句有错误,则显示出错信息,仍然提示当前的汇编地址,用户可重新输入指令。
格式:
A[address]
说明:
若没有指定地址,则从“CS:
100”单元开始存放。
2.U(Unassemed)命令
用途:
对于存贮器内的指令机器码进行反汇编,结果显示的语句和源程序语句会大部分相同,由于不能反汇编出标号、标识符等信息,所以与源程序语句有些差别。
但在调试程序时,这个命令常常用于对照机器码指令与源程序是否一致。
格式:
U[address]或U[range]
说明:
反汇编过程产生的输出包括指令的开始地址,指令的机器码和指令的源语句。
例:
-U:
从当前地址开始反汇编
也可以从某个地址处开始反汇编
例:
-U200:
从CS:
200处开始反汇编
(三)运行命令
1.G(Go)命令
用途:
执行正在调试的程序。
格式:
G[=address][address[address…]]
说明:
等号及第一个address参数指明程序执行的起点。
后面的一个或多个address参数是设定的断点。
这个命令可取以下三种格式:
(1)G不打入任何参数。
这时从当前指令,即从CS:
IP指定的地址开始执行,并一直执行下去。
(2)G=address打