1、汇编语言程序的上机过程,目前根据使用的软件, 汇编语言程序的上机有两种方式, 一种是在DOS状态下逐步调用相关的软件对源程序进行编辑、汇编、 连接和运行,完成整个上机过程的。另一种是在集成环境(IDE)下完成上述上机过程的,此种方式的上机比较方便,用户不必用命令方式多次调用相关软件逐步完成上机过程,而只需要一次调用IDE软件,然后利用该软件的各种功能菜单完成上述上机过程, 整个上机过程只需在一个软件中完成。这是因为该类软件利用了面向对象的程序设计方法将与汇编语言程序上机所需的各种实用程序集成到一个软件中了。尽管该类软件使汇编语言程序的上机方便了许多,但基本的上机步骤仍然与第一种方式相同。为了使
2、初学者对汇编语言的上机过程有个完整的概念,我们仍以第一种上机方式进行介绍。汇编语言程序的上机过程如图 5-1 所示。,图 5-1 汇编语言程序的上机过程,5.6.1 编辑源程序 用户的源程序要输入到计算机内存及以源程序文件方式存入磁盘必须使用编辑程序。编辑程序能处理以字符ASCII形式出现源程序,目前,常用的文字编辑程序,例如ED、WPS、WORD等均具有相应的编辑功能,只是操作上有所不同,但就编辑汇编语言源程序而言,它们都是可行的。用户可任选一种熟悉的编辑程序,输入并编辑要上机的一个源程序。为方便后续各节的介绍,假定输入的源程序文件主名为A1, 程序为从 10 个无符号整数中挑选出一个最大数
3、和最小数。需要注意的是, 完成编辑的源程序文件其扩展名必须是 .ASM。为了便于从输入的源程序中阅读和查错,各个段、标号、各变量和各类指令应排列整齐,重要的地方可以使用注释。A1.ASM的源程序如下:,DATA SEGMENTNUM DW 235,3278,581,2561,357,128,5,5476,12345,7891MAXVDW ?MINVDW ?DATAENDSCOSEG SEGMENT ASSUME DS:DATA,CS:COSEGSTART: MOV AX,DATAMOV DS,AXMOV SI,OFFSET NUMMOV CX,9MOV AX,SIMOV BX,AX,ADD2:
4、 ADD SI,2CMP SI,AXJC CMPMIN ; CF=1JZ NEXTMOV AX,SIJMP NEXTCMPMIN: CMP SI,BX JNC NEXT ; CF=0 MOV BX,SI NEXT: LOOP ADD2 MOV MAXV,AX MOV MINV,BX MOV AH,4CH INT 21H COSEG ENDS END START,5.6.2 汇编源程序,1 MASM的操作 在DOS状态下,调用MASM的操作如下(假定MASM、 CRF、 LINK等软件已在C盘上): CMASM A1.ASM屏幕上显示的信息是: Microsoft (R) Macro Assem
5、bler Version 5.00Copyright (C) Microsoft Crop 19811985, 1987。 All rights rescrvedObject filenameA1.OBJ:,此时宏汇编程序停下来询问用户汇编后产生的目标程序文件名是否为方括号中默认值,若是,可直接键入回车符,否则可以另输入程序文件名, 然后键入回车符,用户回答完这一询问后,宏汇编程序接着依次询问是否需要产生列表文件和交叉引用文件。此时宏汇编程序的提示信息为: Source listing NUL.LST: Crossreference NUL.CRF:,若需要产生目标程序文件名,则应输入相应的文
6、件名;若不需要产生,则只需键入回车符即可。 完成上述人机对话后,宏汇编程序就开始对源程序进行语法检查,同时将各语句汇编成对应的机器指令代码。汇编过程中若发现程序有语法错误, 会随时给出出错信息。出错信息的格式是: 语句所在的源程序文件行 错误信息代码 错误信息的说明 宏汇编程序在最后两行给出此次汇编后的出错总数。其中, 第一行是警告性错误总数,第二行是严重性错误总数。若这两个错误总数均为零,说明源程序的汇编通过, 可以进行连接, 否则要返回编辑程序,修改源程序,然后再次汇编直至汇编正确为止。,2 程序文件的说明 (1) 目标程序文件(.OBJ)。 源程序经汇编后,生成的第一个程序文件是目标程序
7、文件,它是一个二进制代码文件,不能用DOS命令直接在屏幕上显示,也不能被计算机直接执行。生成目标程序文件是汇编的主要目的, 所以这个文件也是用户所需要的。,(2) 列表文件(.LST)。 列表文件对程序的调试提供了很有用的信息。这是因为列表文件同时列出了源程序中的各个语句及对应的目标代码, 各个语句所属段内的偏移地址,使用的段名、段长及有关属性,使用的标号、变量和符号的名字、类型和值,用户可以很方便地通过列表文件查阅指令或数据的偏移地址以及其它信息。下面是源程序A1.ASM经汇编后的列表文件A1.LST的清单:,1 0000 DATA SEGMENT2 0000 00EB 0CCE 0245
8、0A01 NUM DW 235,3278,581,2561,357,128, 5,5476,12345,78913 0165 0080 0005 1564,4 3039 1ED3 5 0014 ? MAXVDW ? 6 0016 ? MINV DW ? 7 0018 DATA ENDS 8 0000 COSEG SEGMENT 9 ASSUME DS:DATA,CS:COSEG10 0000 B8 - R START: MOV AX,DATA11 0003 8E D8 MOV DS,AX12 0005 BE 0000 R MOV SI,OFFSET NUM13 0008 B9 0009 MOV
9、 CX,914 000B 8B 04 MOV AX,SI15 000D 8B D8 MOV BX,AX16 000F 83 C6 02 ADD2:ADD SI,2,17 0012 39 04 CMP SI,AX18 0014 72 07 JC CMPMIN ;CF=119 0016 74 0BJZ NEXT20 0018 8B 04MOV AX,SI21 001A EB 07 90 JMP NEXT22 001D 39 1C CMPMIN: CMP SI,BX23 001F 73 02 JNC NEXT ;CF=024 0021 8B 1C MOV BX,SI25 0023 E2 EA NEX
10、T: LOOP ADD226 0025 A3 0014 R MOV MAXV,AX27 0028 89 1E 0016 R MOV MINV,BX28 002C B4 4C MOV AH,4CH29 002E CD 21INT 21H30 0030 COSEG ENDS31 END START,(3) 交叉引用文件(.CRF)。 源程序汇编后能提供的第三个文件是交叉引用文件。交叉引用文件是为了建立交叉引用表而生成的,交叉引用表给出用户在源程序中定义的所有符号(包括段名、变量名、标号等), 对于每个符号又都列出了其定义的所在行和引用行号的情况, 并按字母顺序排列。用户若想使用交叉引用表,还需调用
11、DOS中的CREF.EXE程序,根据A1.CRF文件建立一个名为A1.REF的文件。若显示A1.REF文件的内容,则可看到该符号表。下面是源程序A1.ASM的交叉引用表文件A1.REF的清单:,Microsoft CrossReference ( definition, + modification) Cref-1ADD2 16 25CMPMIN 1822COSEG 8 9 30DATA 17 9 10MAXV 5 26+MINV 6 27+NEXT 1921 23 25NUM 2 12START 10 319 Symbols,5.6.3 连接目标程序 源程序经过宏汇编后已产生二进制数的目标程
12、序,并以文件方式存在盘上,但它还不是可执行的程序文件,必须使用连接程序(LINK)把目标程序文件转换成重定位的可执行文件(扩展名为 .EXE)。 当一个程序较大且由多个程序模块组成时,也应通过连接程序将它们连接在一起,产生一个可执行文件。经连接程序处理的目标程序可产生二个程序文件, 并且均能自动存入磁盘中, 这二个程序文件名分别是:可执行文件A1.EXE和内存映象文件A1.MAP。其中,A1.EXE文件是用户必须的,内存映象文件可有可无,由用户在连接操作时选择。下面我们对目标程序的连接操作和连接后可能生成的两个程序文件简单介绍如下。,1 连接操作 在DOS状态下, 调用LINK程序的操作如下:
13、 CLINKA1 屏幕上显示信息: Microsoft (R) Overlay Linker Version 3.60Copyright (C) Microsoft Corp 19831987.All rights rescrvedRun file A1.EXE:,连接程序询问用户产生的可执行文件名是否用方括号中的默认值, 若是,则键入回车符,否则可另行输入文件名。 接着显示: List file NUL.MAP: 连接程序询问用户是否需要内存映象文件,若不需要,则可键入回车符,若需要,则要输入文件名。最后显示: Libraries.LIB: 这是连接程序询问用户连接时是否要用库文件, 若无特
14、殊需要, 则用户键入回车符应答。,如果一个较大的程序由多个模块组成,例如,有三个源程序文件A1、 A2和A3组成,则应先将它们分别汇编,汇编后无语法错误,再可使用“+”把它们连接起来, 连接后产生一个可执行程序文件,并约定自动取第一个目标程序文件的主名作为可执行程序文件的主名。其连接操作是: Link A1+A2+A3,2 程序文件的说明 (1) 可执行程序文件(.EXE文件)。 经LINK连接操作后,生成的第一个文件称为可执行程序文件, 它是必须要有的。该程序可在DOS状态下直接运行,也可以通过调试程序DEBUG进行调试运行。,(2) 内存映象文件(.MAP文件)。 它是连接程序的列表文件,
15、又称内存映象文件,该文件列出各个段在内存中的分配情况,主要有各段的名字、起点、终点和长度等信息。 A1.MAP文件的内容显示如下: Start Stop Length Name Class 00000H 00017H 00018H DATA 00020H 0004FH 00030H COSEGProgram entry point at 0002:0000,5.6.4 程序的执行 用户的汇编语言源程序经汇编得到目标程序,目标程序经过连接后得到可执行程序,并且都以文件的形式存在磁盘上。 汇编语言的可执行程序可用下述两种方式运行。 1 DOS状态下运行程序 像其它任何的可执行文件一样,已生成的可执
16、行文件在DOS状态下就可以直接执行,具体操作如下所示: CA1 程序运行过程中,若需要输入数据,则用户就应按规定输入;若有结果,则可从相应的输出设备观察。程序运行结束后自动返回DOS状态。,2 在DEBUG状态下运行程序 当用户程序的正确性无法保证,需要调试时,可将执行文件(EXE文件)置于DEBUG(调试软件)状态下运行。在DOS状态下调用DEBUG程序, 由DEBUG将可执行程序文件从盘上调入内存,在DEBUG状态下利用DEBUG提供的各种命令可以观察、修改寄存器和存储单元的内容,观察每条指令执行的结果。最后达到纠正程序中错误的目的。由于DEBUG中命令很多,限于篇幅本书只介绍其中几个常用
17、命令,其余命令请用户参考有关资料。,(1) DEBUG程序的调用与退出。 在DOS状态下直接调用DEBUG程序, 并同时装入可执行程序的命令格式为: CDEBUG XYZXYZ可执行程序文件名全称。 例如: CDEBUG A1.EXE _ 当DOS将DEBUG及A1.EXE文件装入内存后,系统以“-”作回答, 表示系统已在DEBUG状态下。用户可以在“-”后面直接键入各种DEBUG命令,调试程序。若调试结束,则要退出DEBUG程序返回DOS可使用Q命令。其命令格式为: -Q C,(2) 显示内存单元命令。 其命令格式为: D地址 或 D范围例如: -D DS:200 ;表示从(DS)+200H
18、开始显示80H个字节单元内容 -D DS:200 220 ; 表示从(DS)+200H开始显示20H个字节单元内容,(2) 显示内存单元命令。 其命令格式为: D地址 或 D范围 例如: -D DS:200 ;表示从(DS)+200H开始显示80H个字节单元内容 -D DS:200 220 ; 表示从(DS)+200H开始显示20H个字节单元内容,显示命令的实例如下: -D DS:100 14B6:0100 EB 00 CE OC 45 02 01 0A-65 01 80 00 05 00 64 15 .E.e.d.14B6:0110 39 30 D3 1E 00 00 00 00-00 00
19、 00 00 0000 00 00 90.14B6:0120 B8 C6 14 8E D8 BE 00 00-B9 09 00 8B 04 8B D8 83 .14B6:0130 C6 02 39 04 72 07 74 OB-8B 04 EB 07 90 39 1C 73 .9.r.t.9.s14B6:0140 02 8B 1C E2 EA A3 14 00-89 1E 16 00 B4 4C CD 21 .L.!14B6:0150 18 EF C3 E8 1C 00 E8 53-00 73 0A 80 3E 10 27 FF .S.s.14B6:0160 75 03 F9 EB 0C E8
20、 8A 00-73 03 F9 EB 04 E8 5F 00 U.S.-.14B6:0170 F8 C3 56 51 50 33 C9 80-3C 00 74 29 80 3C 0D 74 .VQP3.t).t,在屏幕上显示的内容分为三部分,最左边部分是每一小段(16个字节组成)的起始地址, 中间部分是每个字节单元的内容, 以十六进制数表示, 右边部分则是用ASCII码字符表示的内容, 若该单元内容是不可显示的字符, 则以“.”表示。,(3) 修改内存单元命令。其命令格式有两种。 它们分别是: E 地址 内容表 即用给定的内容表来替代指定地址范围内的内存单元内容。 例如: -E DS:100
21、8DABCD 该命令可以用上述五个字节的数依次替代以DS:100开始的连续五个字节单元中原先的内容。, E 地址 即采用逐个单元相继修改的方法。 例如: -E DS:100 先显示DS:100 单元原先的内容。假设原内容为79, 若要修改, 则可在 79 后直接输入两位新的十六进制数,以替代原来的内容。若要结束修改,则按回车键返回“-”状态。 若需要连续修改, 则有以下两种不同操作可供选择:, 再按空格键, 接着显示下一个高地址单元的内容, 这样可以从低地址到高地址逐个单元地修改。 例如: 18E4:0100 79 56 85 75 43 按“”键, 显示前一个低地址单元内容, 并等待输入新的
22、数据。这样可以从高地址向低地址逐个单元地修改其内容。例如: 18E4:0100 79 ,(4) 显示寄存器内容命令。 命令格式为: R 键入R命令后,屏幕上会显示CPU各寄存器的内容,第二行后半部分显示的是标志寄存器的各标志位状态,它们是以字符形式表示。 第三行显示的是当前的CS:IP值及该值指向的指令, 即是下一条将要执行的指令。例如: RAX=0000 BX=0000 CX=0050 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000DS=14B6 EX=14B6 SS=14C6 CS=14C8 IP=0000 NV UP EI PL NZ NA PO NC14
23、C8:0000 B8C614 例如: MOV AX,14C6,(5) 修改寄存器内容命令。其命令格式为: R 寄存器名例如: R AX系统响应: AX 1E84 : 若用户要想修改AX寄存器内容,则可在“:”后直接键入修改的内容,否则按回车符,返回“”状态。,() 反汇编命令。 将目标代码还原为源程序的符号指令的操作称为反汇编。 目标代码反汇编后除了能显示出源程序的符号指令,还能显示每条指令的物理地址, 这些地址可为G命令中设置断点地址提供方便。 其命令格式为: U 地址 或 U 地址范围,前一种命令格式从指定的地址开始显示 32 个字节目标代码的源程序符号指令,若地址被省略,则从上一个U命令
24、的最后一条指令的下一个单元开始显示 32 个字节的所对应的符号指令,后一种命令格式是在用户指定的地址范围内进行反汇编(结束地址用偏移量表示)或指定起始地址和长度。 例如: U CS:0 ; 显示CS指向段的前 32 个字节目标代码的符号指令 U CS:10 20; 显示偏移地址为 10H到 20H范围内的目标代码的符号指令 U CS:10 L 10 ; 同上,U命令实例为: U CS:0 14C8:0000 B8C614MOVAX, 14C614C8:0003 8ED8MOVDS, AX14C8:0005 BE0000MOVSI, 000014C8:0008 B90900MOVCX, 0009
25、14C8:000B 8B04MOVAX, SI14C8:000D 8BD8MOVBX, AX14C8:000F 83C602 ADDSI, +0214C8:0012 3904 CMPSI, AX14C8:0014 7207 JB 001014C8:0016 740B JZ 002314C8:0018 8B04 MOVAX, SI14C8:001A EB07 JMP002314C8:001C 90NOP14C8:001D 391C CMPSI, BX14C8:001F 7302 JNB0023,(7) 程序运行命令。 可执行程序文件由DEBUG装入后,可在DEBUG状态下用以下两种不同方式运行目
26、标程序,一种称为连续运行方式,另一种称为跟踪运行方式。 连续运行方式。 连续运行方式是通过命令使整个可执行程序从头到尾运行一次或是将整个程序分为若干段进行分段运行。 命令格式为: G =地址 1 , 地址 2 , 地址 3,若该命令不带地址参数,则程序就从开始处运行至结束。 若命令带有地址参数,则程序就按指定的地址分段执行。 命令中的地址参数均以指令的偏移地址表示,其中,=地址是运行程序的起始地址,起始地址以后的地址参数又称为断点地址,断点地址是一条指令的首字节地址,也以偏移地址表示。 当程序执行到由断点地址指定的断点处,程序就停止执行并显示当前所有寄存器的内容和下一条将要执行的指令。需要注意
27、的是,断点地址只对本次G命令有效。若再次使用G命令,需重新设置断点地址。设置断点的好处是将一个大的程序分为若干段, 逐段观察运行结果, 便于发现程序设计的错误。, 跟踪运行方式。为了逐条观察指令的执行结果,可以使用跟踪命令。使用跟踪命令后,每执行完一条指令后,就自动显示所有寄存器的内容及下一条要执行的指令。 跟踪命令有T命令和P命令两种。 T命令格式为: T =地址 值,其中,=地址为指定T命令开始执行的指令地址, 若省缺, 就以CS和IP现有内容作起始地址。 值是T命令运行的指令条数(十六进制), 若值省缺, 则被视为值=1, 即只执行一条指令。,例如: T=0 2AX=14C6 BX=00
28、00 CX=0050 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000DS=14B6 ES=14B6 SS=14C6 CS=14C8 IP=0003 NV UP EI PL NZ NA PO NC14C8:0003 8ED8 MOV DS, AXAX=14C6 BX=0000 CX=0050 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000DS=14C6 ES=14B6 SS=14C6 CS=14C8 IP=0005 NV UP EI PL NZ NA PO NC14C8:0005 BE0000MOV SI, 0000,P命令格式为:
29、 P =地址值其中,=地址为指定P命令开始跟踪的指令地址,若为偏移地址, 则段基址在CS寄存器中,若省缺,则地址从当前的CS: IP指示的地址开始,值是P命令运行的指令条数,若值省缺,则被视为值=1,即P命令只运行一条指令。与T命令不同的是, P命令一旦执行到DOS功能调用、 BIOS功能调用、 子程序调用指令、LOOP类指令或重复的串操作指令时,将之作为一条指令对待, 并将对应的全部操作(子程序中的所有指令, 重复操作中的所有指令)执行完毕(而不是跟踪其中每一条指令)。 然后显示上述五类指令执行后的各寄存器的内容及下一条要执行的指令。 例如:P2 表示从当前CS: IP地址开始连续执行两条指令, 每执行一条指令后显示所有寄存器的内容及下一条要执行的指令。,