微型计算机原理与汇编语言实训教程
第一章 IBM PC系列微机的操作
1.1 汇编语言程序的操作过程
汇编程序是把用汇编语言编写的原代码翻译成计算机能够识别的机器语言的目标模块。
为微机提供的汇编程序有两种版本:一是小汇编程序ASM,小型版本占用存储空间少,有64KB的内存就可以运行,小型版本不支持宏指令以及有关的功能,只能有限制地使用伪指令;二是宏汇编MASM,它至少要96KB以上的内存才能运行。宏汇编程序包括小汇编的功能,同时可以使用所有的宏指令和伪指令。
宏汇编程序在磁盘操作系统DOS下运行。
要建立和运行用户自己编写的汇编语言,系统盘上必须有如下文件:
① EDIT.COM(或WORDSTAR全屏幕编辑程序或EDLIN行编辑程序);全屏幕编辑程序。
② MASM.EXE;宏汇编程序。
③ LINK;连接程序。
④ DEBUG.COM;调试程序。
正常运行的汇编语言源程序一般要经过编辑、汇编、连接和调试四个步骤:
(1) 编辑源程序 调用上述任一种编辑程序,输入源程序并以 .ASM文件格式存盘。
(2) 汇编程序 由编辑程序建立的.ASM文件是文本文件,不能在计算机上运行。需要经过汇编后,将其转化为代码文件,后缀.OBJ。如果在源程序中有任何语法错误,宏汇编将列出错误信息。
经过汇编后可产生三个文件,即:机器码的目标文件OBJ,列表文件LST和交叉文件CRF。
(3) 连接程序 目标文件是浮动的相对地址,不能直接执行,须经过连接程序LINK,将若干个目标文件模块连接起来,把程序中可浮动的相对地址变为绝对地址,形成可执行的.EXE文件,然后就可以在DOS状态下执行程序。如执行结果出错,可调用调试程序对可执行文件进行调试。
(4) 调试程序 DEBUG是调试汇编语言程序的工具,它可以通过设置单步或断点等方法,显示有关存储单元或寄存器的内容,从而较容易地找出程序中的错误。经过DEBUG调试后的程序,必须重新进行编辑、汇编、连接,才可执行。
1.2 屏幕编辑程序EDIT
文本编辑程序EDIT.COM是DOS外部命令,用来建立,修改,显示和存储文本文件。这是全屏幕编辑程序。本文介绍的是美国微软公司1995年推出的2.0版本。
1.2.1 EDIT的启动
EDIT的启动同其他DOS外部命令一样,只需在DOS提示状态下键入:
EDIT[文件名]
其中:[文件名]是一个任选项,如指定文件名,EDIT就装入指定的文件以供编辑。如果不指定文件名,则EDIT建立一个无名文件,其后文件存盘时要求给出文件名。
在键入EDIT命令行后,立即出现编辑屏幕显示。如图1.2所示。
光标停在编辑窗口内第1行第1列位置,行列数在屏幕右下角标出:Line:1Col:1。
File Edit Search View Option Help -------------------------------UNTITLED1----------------------------- ↑
↓ |
|
F1=Help |
Line:1 Col:1 |
图1.2 EDIT编辑屏幕
开始 |
调用编辑程序 |
建立源文件 |
人工检查错否? |
已.ASM文件存盘 |
调MASM程序汇编源文件 |
语法有错? |
生成.OBJ文件 |
调LINK程序,连接目标文件 |
连接有错? |
生成.EXE文件 |
执行.EXE文件 |
结果有错? |
结束 |
用DEBUG查错 |
Y |
Y |
Y |
N |
N |
N |
N |
Y |
修改源程序 |
1.2.2 请求帮助的方法
对于EDIT的初学者或是对EDIT命令不十分熟悉的用户,在编辑状态下,可以随时请求帮助。取得帮助信息的方法有两种:
① 选择菜单命令Help的各子命令。
② 在编辑状态下,按F1键,屏幕即显示帮助信息。
1.2.3 EDIT部分编辑命令
在编辑状态下,按F1键,屏幕即显示EDIT的编辑命令。
1)光标的移去
光标的移动通过光标移动命令实现,如表1.1所列。
表1.1 光标移动命令
键名 |
功能 |
Home End Ctrl+↑ Ctrl+↓ PageUp PageDown Ctrl+PgUp Ctrl+PgDn Ctrl+Home Ctrl+End Ctrl+← Ctrl+→ |
光标移至行首 光标移至行尾 屏幕向上卷一行 屏幕向下卷一行 屏幕向上翻一屏 屏幕向下翻一屏 光标向右移一屏 光标移至文件头 光标移至文件尾 光标左移一个英文单词 光标右移一个英文单词 |
光标移动是指移动光标位置,而不改变光标处的内容。光标只能在光标扫描过的区域或已有字符的区域内移动。
2)文本的输入
在光标处键入字符或空格,则光标向右移动一个字符位置,原来光标处显示相应的字符或空格。
输入完一行按回车键结束。如一行的内容超过一屏显示宽度(每屏最多显示80个字符),可以继续输入,直到输入完按回车键为止。超出屏宽的字符从行首被逐一“挤”出屏外。
3)文本的修改
文本输入过程中难免出错,这就要求对文本进行修改。下面介绍一系列的文本修改命令。
(1) 插入及覆盖状态的切换用INS键,当按该键的奇,偶次将交替产生插入或覆盖状态。插入状态。插入状态下时,光标表现为字符下方的小光标;覆盖状态时,光标表现为覆盖字符的大光标。
在确认系统处于插入状态后,便可以移动光标要插入字符的位置处,键入要插入一个或多个字符,此时新键入的内容被插入到当前光标处,而原来的内容“挤”向了右边。
在确认系统处于覆盖状态后,将光标移到欲覆盖的字符所在位置处,键入一个或多个字符,则新的字符将自动地覆盖旧的字符。
(2) 断行与接行 如果要将某一行断成两行,在插入状态下,将光标移至欲断处,按回车键,光标以后的内容即另起一行。
如果要将相邻的两行接成一行,可将光标移至前一行的行尾,按DELETE键或CTRL+G键;也可将光标移至后一行的行首,按Backspace键或Ctrl+H键。
(3) 删除操作 可以通过删除操作删除一个,一串或一行字符.
将光标移至待删除的字符处,按DELETE键或CTRL+G键,该字符即被删除,同行右边的字符自动向左移位,填补上这个空位。
如果要删除一个英文单词,可将光标移至待删除字符串的最左边,按CTRL+T键,便可将当前光标处向右一个英文单词删除。同时该行光标右侧的字符自动向左移位,填补空位。
如果要删除一行字符,可将光标移到欲删除的行上,按CTRL+Y键,就可将此行删除。同时下边的行逐行向上移动。
表1.2 删除命令
键名 |
等效组合键 |
功能 |
Delete Backspace |
Ctrl+G Ctrl+H Ctrl+T Ctrl+Y |
删除当前光标处的一个字符 删除当前光标左边的一个字符 删除当前光标开始向右的一个英文单词 删除当前光标所在行 |
(4) 块操作 “块”是指文件块,所谓文件块中的一部分文本。文件块的定义方法是:在块首同时按下SHIFT键和→键,直到块尾;或在块尾同时按下SHIFT键和←键,直到块首。若块范围超过一行,则在块首按下SHIFT+→键后按SHIFT+↓键;或在块尾按下SHIFT+←后按SHIFT+↑键。
在文件块定义好之后,按SHIFT+DEL键,则文件块从原位置消失。将光标移至欲插入该文件块的地方,按SHIFT+INS键,则文件块在新的位置插入,完成了文件块的移动。
如果在文件块定义好之后,按CTRL+INS键,则文件块在原位置没有变化,但将光标移到新位置按SHIFT+INS键,则将文件块在新的位置插入,完成了文件块的复制。
如果在文件块定义好之后,按DEL命令,将删除文件块。
1.2.4 命令菜单的使用
依编辑窗口下边的提示,按下Alt键即进入菜单。这时编辑窗口上边的六个命令项(FILE,EDIT,SEARCH,VIEW,OPTIONS,HELP)的第一个字母呈高亮度显示,光标停在第一个命令File上。为了选择其中一个命令项,可以键入高亮度字母F,E,S,V,O,H之一,或用→←键移动光标至所选项再回车。
一个命令项被选中后,立即出现该命令项的下一级菜单。图1.3列出了各命令项及其子命令菜单。如退出命令菜单,可按ESC键。
File |
Edit |
Search |
View |
Options |
Help |
||||||
|
图1.3 命令菜单
1) File命令项
为了选择NEW,OPEN,SAVE,SAVE AS,PRINT,EXIT六个子命令之一,可以键入高亮字母N,O,S,A,P,X之一,可用↑↓键移动光标到所选项后再回车。
(1) NEW命令 选中NEW命令后,屏幕显示:编辑的文件没有存盘,现在存盘吗?用TAB键选择屏幕上的YES则存盘,选择NO则放弃存盘,选择CANCEL则退出命令,选择HELP则提供帮助信息,用TAB键可使光标停在OK上回车,即回到原菜单。
(2) OPEN命令 选中OPEN命令后,键入一个已经建立的文件的路径和名字,则可在原编辑屏幕上打开和显示这个文件内容。
(3) SAVE命令 选中SAVE命令后,则将编辑的文件存盘,如果没有文件名,则要求输入一个文件名。
(4) SAVE AS命令 选中PRINT命令后,若编辑的文件有文件名,则认可后按回车键。若要修改文件名或原来没有文件名,则输入新的文件名再按回车键。不论哪种情况,按回车键后文件存盘。修改文件名的时候,老文件仍然留在盘上。
(5) PRINT命令 选中PRINT命令,可以打印部分文本或全部文本。如果光标在帮助窗口,则可以打印部分或全部帮助文本。
(6) EXI命令 选中EXIT命令,则退出命令菜单。如果文件没有存过盘,则将提醒用户存盘。
2) EDIT命令项
用↑↓键可以移动光标到CUT,COPY,PASTE,CLEAR四个子命令之一上,但按回车键盘能输入光标所在处命令。这四个子命令也没有高亮度字母显示。这是因为在使用这四个子命令之前,必须先定义文件块。
当文件块定义好之后,再进入EDIT命令菜单时,字母T,C,E呈高亮度显示。可以键入高亮度字母T,C,E之一,或用↑↓键移动光标到反选项后再回车,选择CUT或COPY或CLEAR子命令。
(1) CUT和PASTE命令 CUT命令和PASTE两命令结合,可以完成文件块的移动。
在文件块定义好之后,选择CUT命令从原来位置消失。这时可将光标移到欲插入这个文件块的地方,再进入EDIT命令时,PASTE的第一个字母P也呈高亮度显示。按下字母P,或将光标移到PASTE命令,然后按下ENTER键,于是就插入了这个文件块。
多次选用PASTE命令,可以在多处重复插入这个文件块,还可以在一个打开的新文件或已建立的老文件中插入这个文件块。
(2) COPY命令和PASTE命令 COPY和PASTE两命令结合,可以完成文件的复制。
定义了文件块之后,选择COPY命令,定义的文件块没有变化。将光标移到欲复制这个文件块的地方,选择PASTE命令,就复制了这人文件块。
多次选用PASTE命令,可以在多处重复插入这个文件块,还可以在一个打开的新文件或已建立的老文件中插入这个文件块。
(3)CLEAR命令 定义了文件块后,选择CLEAR命令,将把这个文件块从文件中删除。
EDIT的四个子命令也可以用按键选择:CUT命令用SHITF+DEL键,COPY命令用CTRL+INS键,PASTE命令用SHIFT+INS键,CLEAR命令有DEL键。
3) SEARCH命令项
为了选择FIND,REPEAT LAST FIND,REPLACE三个子命令之一,可以键入高亮度字母F,L,R之一,或用↑↓键移动光标到所选项后再回车。REPEAT LAST FIND命令也可用按键F3选择。
(1) FIND命令 选中FIND命令,屏幕将显示提问:找什么?这时输入要查找的字符串,长度最多127个字符。若文件中几处出现这个字符串,则找到的是从原光标位置算起第一次出现的字符串。若文件中没有这个字符串,则屏幕显示找不到。
(2) REPEAT LAST FIND命令 选中PEPEAT LAST FIND命令,将重复上次的查找。不断地选用这个命令,将把文件中所有这样的字符串查找出来。如果文件中这个字符串只出现了一次,则使用这个命令后光标位置不变。
(3) REPLACE命令 选中REPLACE命令,屏幕将显示提问:找什么?回答后,按TAB键,继续提问:换成什么?回答完了则光标后面第一个找到的字符串被一个新的字符串替换了。如果要找的字符串不止一个,则按下一次ENTER键,有一个字符串被替换,直到所有相同的字符串被替换完毕。
4)VIEW命令
在该命令项*中SPLIT WINDOW,SIZE WINDOW,CLOSE WINDOW及1 UNTITLED1四个子命令。仅有SPLIT WINDOW和1 UNTITLED1两个子命令中的S、1呈高亮度,但如使用了SPLIT WINDOW子命令后,其余两个子命令中的I和C即呈高亮度。可用↑↓键移动光标选择使用,也可用按键CTRL+F6,CTRL+F8,CTRL+F4及ALT+L选择使用。
(1) SPLIT WINDOW命令 SPLIT WINDW命令用于将屏幕一分为二,光标停在下面第一行第一列的位置,输入的内容同时送入上下两个屏幕,但光标的移动不会影响另一屏幕。用F6键可使光标在两个屏幕之间移动。
(2) SIZE WINDOW命令 当分屏后,选中该命令可用↑↓键改变两个屏幕的大小,改完后按回车键确认。
(3) CLOSE WINDOW命令 选中该命令可将原来的两个屏幕合二为一。
(4) 1 UNTITLED1命令 如果使用EDIT[文件名]命令,其中[文件名]是多个文件名时,则在VIEW命令项中将这些文件名依次列出,并在前面加上序号,且序号呈高亮度,选中一序号即将序号后的文件显示在屏幕上,以供编辑。
5) OPTIONS命令项
为了选择SETTING和COLORS两个子命令之一,可以键入高亮度字母S,C之一,或用↑↓键移动光标到所选项后再回车。
(1) SETTING命令 使用该命令可以设置:
① TAB键的宽度。 默认值为8列。
② 打印口的位置。可按TAB键移动光标,选择打印口的位置,然后按回车键确认。
(2) COLORS命令 COLORS 命令用于确定屏幕显示的前景与背景颜色。前景提供了蓝,绿,青,红,洋红,棕,白7种颜色。背景提供了黑,绿,青,红,洋红,棕7种颜色。选中COLORS命令后,可用TAB键选项,用↑↓键移动光标到所选颜色后按回车。按↑↓键能在选择屏幕上同时有选择效果显示。
6) HELP命令
为了选择COMMANDS,ABOUT两个命令之一,可以键入高亮度字母C,A之一,或用↑↓键移动光标到所选顶后再回车。
① COMMANDS命令(见表1.1)
② ABOU命令 选中这个命令将显示MS-DOS EDITOR的版本号及版权信息。
1.2.5 EDIT的使用条件
EDIT命令运行QBASIC.EXE文件和EDIT核心文件EDIT.COM。如果要求使用帮助信息,还必须有EDIT.HLP文件。若删除了QBASIC.EXE,则EDIT将无法运行。
1.2.6 编辑源程序举例
假设下面的汇编语言源程序运行后能将以下BUF单元开始的10个存储单元清零,并在屏幕上显示出来。
NAME EXAM
DATA SEGMENT
BUF DB 10 DUP(?),’$’
DATA ENDS
STACK SEGMENT PARA STACK ’STACK’
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET BUF
MOV CL,0AH
LP: MOV BYTE PTR [BX],30H
INC BX
DEC CL
JNZ LP
MOV DX,OFFSET BUF
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
现在用编辑程序EDIT将原程序输入到计算机中。首先键入:
C:/>EDIT↙
屏幕显示版权信息。按ESC键进入编辑屏幕,与图1.2所不同的只是没有文件名。
光标停在第一行,第一列的位置。用键盘输入程序,一行结束按回车键,光标移到下一行,再继续输入,直到全部输入完毕。输入的程序显示如下:
NAME EXAM
DATA SEGMENT
BUF DB 10 BUF (?),’$’
DATA ENDS
STACK SEGMENT PARA STACK ‘STACK’
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET BUF
MOV CL,0AH
LP: MOVW [BX],30H
INC BX
DEC BX
DEC CL
JNZ LP
MOV DX,OFFSET BUF
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
查看输入的程序,发现第9行的ASSUME少了一个S,第16行多了DEC BX。利用EDIT的编辑功能对它们进行修改:按光标移动键↑↓→←,可将光标移动到出错的位置,首先移动到ASUME的S处,插入一个S;再将光标移到DEC BX处,按CTRL+Y键,删除光标所在行。
修改完毕后,按ALT键激活菜单,选择FILE命令的SAVE子命令,回答文件名为EXAM.ASM,将源程序存盘。再选择FILE命令的EXIT子命令,退出EDIT。
1.3 汇编程序MASM
汇编就是把用汇编语言编写的源程序汇编成机器语言的目标程序。
能用宏汇编通过的汇编语言源程序必须是一个完整的程序,有各逻辑段的定义。
启动MASM命令的语法格式如下:
C:/[路径]>MASM[源文件名][,[目标文件名][,[列表文件名][,[交叉索引文件名]]]][; ]([ ]可选项)。
1.3.1 操作方式
在对源文件进行汇编之前,必须准备好一张汇编系统盘,包含有以下文件:
MASM 宏汇编程序
LINK 连接程序
CREF 索引程序
LIB 库管理程序
也可以将这些文件复制到硬盘的一个子目录下。
汇编程序有两种操作方式:对话方式和命令方式。
1)对话方式
假设MASM在C盘ASM子目录下,盘中有一EXAM.ASM文件,调入MASM,屏幕显示与操作如下:
C:/ASM>masm ↙
Microsoft(R)Macro Assembler Version 5.00
Copyright(c)Microsoft Corp 1981-1985,1987,All right reserved
Source filename[.ASM]:myfile ↙
Object filename[EXAM.OBJ] ↙
Source listing[NUL.LST] ↙
Cross-reference[NUL.CRF] ↙
51480+405967 Bytes symbol space free
0 Warning Errors
0 Severe Errors
宏汇编程序被调入以后,首先显示版本号。然后依次提出问题,请用户回答。
第一行提问被汇编的源文件的名字,方括号内表示此文件带有后缀.ASM(.ASM是该源程序文件的隐含扩展名),此时应键入将要汇编的源程序文件的名字,并按回车键。这里用的文件名是EXAM.ASM。
第二行提提问汇编后目标文件的名字,括号中的名字表示约定的文件名(其文件名部分自动采用源程序文件名),若采用这个名字则直接键入回车键。否则键入另起的名字。
第三行提问是否要建立列表文件。括号中的NUL为“空”的意思,表示不建立列表文件。若要建立列表文件,则需键入文件名,名字任选,也可与源程序文件名同名。但后缀必须为.LST,后缀可由用户连同文件名一起键入,也可不键入,即自动采用隐含值。如果不需要建立列表文件,则在第三行提问后直接按回车键。
第四行提问是否要建立交叉索引文件,括号中的意义同第三行,若不需要交叉索引文件,可直接按回车键,否则键入交叉索引文件名。
在各项提问一一回答之后,汇编程序才开始对源程序进行汇编。若源程序没有语法错误,则汇编成功,生成所要求的文件。
在回答提示信息时,可以使用以下两个命令字符:
(1); : 用于省略对后续提示的回答,仅取缺省值。
(2)CTRL+C: 当因为输入了错误的文件名或其他原因而想中途退出汇编程序时,按下CTRL+C键即可退出。
2) 命令方式
以命令方式使用汇编程序时,必须在MS-DOS下键入下列格式的命令:
MASM<源文件>,[<目标文件>],[<列表文件>],[<交叉参考文件>] ↙
于是立即开始进行汇编。命令中MASM后面的项目,分别顺序对应于对话方式中对各提示信息的回答,各项目之间用逗号隔开。如果对某一提示信息采用缺省值,则只需在对应的位置连续输入两个逗号。例如:
MASM EXAM,,EXAM.LST,EXAM.CRF ↙
1.3.2 汇编出错信息
汇编过程中,若发现源程序中有语法错误,则在显示器(也可以为打印机,取决于系统标准输出设备的设置)上列出有错误的语句和错误代码,并指出错误的类型,汇编完后列出警告性错误(Warning Error)和致命错误(Severe Error)的总数。若有致命性错误时,则汇编不成功,要根据汇编程序提示的错误信息分析错误原因,再用编辑程序进行修改,然后重新调用汇编程序进行修改。重复上述步骤,直至错误消除。通常警告性错误不影响目标文件的生成。
1.3.3 打印列表文件及交叉索引文件
若在汇编中要求生成列表文件或交叉索引文件,则在汇编后可以将它们打印出来。
打印出列表文件,可以了解汇编后的情况并做文件保留。
打印列表文件的方法为:
C:/ASM>TYPE<列表文件名>.LST↙
打印出交叉索引文件,可以了解源程序中的符号定义和引用情况。
打印交叉索引文件的操作步骤为:
C:/ASM>CREF↙
Cref filename[.CRF]:<交叉索引文件名>↙
List filename[<交叉索引文件名>.REF]:↙
C:/ASM>TYPE<交叉索引文件名>.REF↙
在第1行提示下,打入汇编时在第4行询问时所键入的交叉索引文件名。
第2行提示,可直接回车,表示采用括号中的文件名。
第3行的TYPE命令就要打印出交叉索引的列表文件了。
1.3.4汇编操作举例
以1.2.6节编辑程序产生的汇编语言源程序EXAM.ASM为例说明汇编的过程。
EXAM.ASM可以在编辑状态中打印出来,也可以在DOS下用TYPE命令打印出来。
汇编
C:/ASM>MASM↙
MICROSOFT(R)MACRO ASSEMBLER VERSION 5.00
COPYRIGHT(C) MICROSOFT CORP 1981-1985,1987,ALL RIGHT RESERVED
SOURCE FILENAME[.ASM]:EXAM↙
ODJECT FILENAME[EXAM.OBJ] ↙
SOURCE LISTING[NUL.LST] ↙
CROSS-REFERENCE[NUL.CRF] ↙
EXAM.ASM(14):ERROR A2035:OPERAND MUST HAVE SIZE
50480+405976 BYTES SYMBOL SPACE FREE
0 WARNING ERRORS
1 SEVERE ERRORS
汇编发现EXAM.ASM的第14行有错误,错误代码A2035,错误提示是“操作数必须有大小”。因为有致命性错误,所以汇编没有成功,没有产生目标文件。
检查源程序,第14 行是:
LP: MOV [BX],30H
操作数类型不明确,返回编辑状态,改为:
LP: MOV BYTE PTR[BX],30H
明确30H送BX所指的字节。程序为:
NAME EXAM
DATA SEGMENT
BUF DB 10 DUP(?),`$`
DATA ENDS
STACK SEGMENTPARA STACK`STACK`
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET BUF
MOV CL,0AH
LP: MOV BYTE PTR[BX],30H
INC BX
DEC CL
JNZ LP
MOV DX,OFFSET BUF
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
重新汇编这个程序,并生成列表文件和交叉列表文件。
C:/ASM>MASM↙
MICROSOFT(R)MACRO ASSEMBLER VERSION 5.00
MCOPYRIGHT(C) MICROSOFT CORP 1981-1985,1987,ALL RIGHT RESERVED
SOURCE FILENAME[.ASM]:EXAM↙
ODJECT FILENAME[EXAM.OBJ] ↙
SOURCE LISTING[NUL.LST] ↙
CROSS-REFERENCE[NUL.CRF] ↙
50480+405976 BYTES SYMBOL SPACE FREE
0 WARNING ERRORS
0 SEVERE ERRORS
2)输出列表文件
C:/ASM>TYPE EXAM.LST↙
MICROSOFT(R)MACRO ASSEMBLER VERSION 5.00 6/20/00
1 NAME EXAM
2 0000 000A[ DATA SEGMENT
3 0000 ?? BUF DB 0A DUP(?),`$`
4 ]
5
6
7 000A DATA ENDS
8 0000 STACK SEGMENT PARA STACK`STACK`
9 0000 0064[ DB 100 DUP(?)
10 0000 ??
11 ]
12
13 0064 SEACK ENDS
14 0000 CODE SEGMENT
15 ASSUME CS:CODE,DS:DATA,SS:STACK
16 0000 B8...... R START: MOV AX,DATA
17 0000 8E D8 MOV DS,AX
18 0005 BB 0000 R MOV BX,OFFSET BUF
19 0008 B1 0A MOV CL,0AH
20 000A C6 07 30 LP: MOV [BX],30H
21 000D 43 INC BX
22 000E FE C9 DEC CL
23 0010 75 F8 JNZ LP
24 0012 BA 0000 R MOV DX,OFFSET BUF
25 0015 B4 09 MOV AH,09H
26 0017 CD 21 INT 21H
27 0019 B4 4C MOV AH,4CH
28 001B CD 21 INT 21H
29 001D CODE ENDS
30 END START
MICROSOFT(R)MACRO ASSEMBLER VERSION 5.00 6/20/00
Segmments and Group:
Name Length Align Combine Class
Code 001D PARA NONE
Data 000A PARA NONE
Stack 0064 PARA NONE ’STACK’
Symbols::
Name Type Value Attr
BUF L BYTE 0000DATA LENGTH=000A
LP L NEAR 000A CODE
START L NEAR 0000 CODE
@FILENAME TEXT EXAM
24 Soutce Lines
25 Total Lines
8 Symblis
50402+407054 Bytes symbol space free
0 Warning Errors
0 Severe Errors
清单中给出了源程序行、目标代码及其在段内存放的偏移地址的一个对照表。当源程序出现语法错误时,MASM则在错误行后面给出错误性质提示。清单的最后部分为段名表和符号名表,表中分别给出段名、段的大小及有关属性,以及用户定义的符号名、类型及属性。
3)产生交叉索引文件并输出
如果在汇编中已生成.CRF交叉索引文件,可通过下面调用产生.REF交叉索引文件。
C:/>CREF↙
MICROSOFT(R) CROSS-REFERENCE UTILITY YERSION 5.00
COPYRIGHT (C) MICROSOFTCR CROP 1981----1985,1987.ALL RIGHTS RESEREVD
CROSS-REFERENCE [.CRF]:EXAM↙
LISTING [EXAM.REF]:↙
6 SYMBOLS
C:/>TYPE EXAM.REF
MICROSOFT CROSS-REFERENCE VERSION 5.00 Thu Jun 20 15:44:43 2000
SYMBOL CROSS-REFERENCE (#DEFINTION,+MODIFICATION) CREF-1
BUF 3# 18 24
CODE 14# 15 29
DATA 2# 7 15 16
LP 20# 23
STACK 8# 8 13 15
STACK 16# 30
6 Symbols
1.4连接程序LINK
用汇编语言编写的源程序经过汇编程序(MASM)汇编后产生了目标程序(.OBJ),该文件是将源程序操作码部分变成了机器码,但地址是可浮动的相对地址(逻辑地址),因此必须经过连接程序LINK连接后才能运行。连接程序LINK是一把一个或多个独立的目标程序模块装配成一个可重定位的可执行文件,扩展名为.EXE文件。在DOS状态下,可直接输入该文件名来执行这个程序。此外还可以产生一个内存映像文件,扩展名为.MAP。LINK命令格式如下:
C:/[路径]>LINK [目标文件名][,[执行文件名][,[列表文件名][,[库文件名]]]][; ]([ ]可选项)
1.4.1操作方式
在DOS状态下,键入LINK↙(或LINK[选项]),调入连接程序屏幕显示有关信息,提示用户逐行回答。
C:/ASM >LINK ↙
MICROSOFT (R) OVERLAY LINKER VERSION 3.60
COPYRIGHT (C) MICROSOFT CORP 1983-1987. ALL RIGHTS RESERVED
OBJECT MODULES[.OBJ]:EXAM ↙
RUN FILE [EXAM.EXE]: ↙
LIST FILE [NULL.MAP]: ↙
LIBRARIES [.LIB]: ↙
第1行提示要求输入目标模块名。此时应键入要连接的目标文件名(后缀.OBJ可省略,LINK程序自动加上.OBJ为后缀)。若连接的是多个目标模块,需用+号或空格将各文件名隔开,如果一行放不下,就在该行的最后输入一个+号,然后按回车键,连接程序就提示用户追加目标文件。全部输入完毕后回车。
第2行提示要求输入将要生成的可执行文件的文件名,括号内为LINK程序给出的隐含文件名,它与第1行提示中的目标模块名一致,只是将后缀换成.EXE。当用户认为方括号中的文件名就是要键入的文件名时,可在冒号后面只键入回车。若第1行回答的是多个目标模块,则隐含的可执行文件名取为第一个目标文件名。此行可不输入文件名而直接回车。
第3行提示问是否要建立列表(映像)文件,若要建立,可键入列表文件名,这时可不输入扩展名,由LINK程序自支按隐含值.MAP为扩展名。如果不想要列表文件,此行提示时直接按回车键即可。对于小型,简单程序在使用中一般不建立列表文件。
第4行提示问是否需要连接库文件。对于连接汇编语言源程序的目标文件,通常是不需要的,因此直接按回车键。
1.4.2 执行程序
当用连接程序LINK将目标程序(.OBJ)连接定位后,可产生可执行文件(.EXE),可以在DOS状态下执行该程序。
执行操作如下:
C:/ASM>EXAM↙
0000000000
在执行程序后可以看到执行结果,是因为源程序中有显示结果的指令,有的程序如果没有显示结果指令,要想看到结果,可以通过DEBUG调试程序来达到目的。
1.5调试程序DEBUG
汇编语言经过编译,连接后生成目标代码。当运行目标代码时,可能出现错误的结果,如果直接查找错误就比较麻烦。DEBUG是一个专门为调试汇编语言程序而设置的工具,它可以检查和修改存储器及寄存器的内容,装入或启动运行程序,它还可以用来直接汇编简单的汇编语言程序,为用户提供了极大的方便。
当然在DEBUG状态下运行汇编程序也具有一定局限性:
①在DEBUG状态下运行程序不能使用宏汇编程序中的宏指令,大部分伪指令也不能使用,只能调试其程序段。
②不能调试太长的程序,只能分块进行程序设计。
③在DEBUG状态下调试好的程序不能形成以DOS外部命令形式构成的 .EXE文件,因此调试好的程序只能记下,到编辑环境下重新键入调试好的程序,通过汇编程序,连接程序形成可执行文件 .EXE。
1.5.1 DEBUG 的调用
1) DEBUG 的启动
DEBUG的启动格式如下
(1) DEBUG
(2) DEBUG[<路径名>][<参数>]
这里的路径名是指被调试程序的路径,而参数是包括在被调试程序名中的各参数。例如
C:/ASM>DEBUG EXAM.EXE↙
此命令把DEBUG程序调入内存后,DEBUG程序又把调试的程序调入内存中。若是启动格式(1),则DEBUG程序是以当前内存的内容工作。
在DEBUG成功地调入内存后,将显示提示符“-”,说明系统现在是在DEBUG程序管理之下。DEBUG所属的命令,只有出现DEBUG提示符后才能有效。
2)寄存器和标志位的初始化
进入DEBUG后,各寄存器和标志位被初始化,其值可用寄存器显示命令查看。例如:在用第一种格式启动DEBUG后
-r↙
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=16AD ES=16AD SS=16C0 CS=168C IP=0000 NV UP EI PL NZ NA PO NC
168C:0100 B8368021 MOV SI,[2180]
在用第二种格式启动DEBUG后
-r↙
AX=0000 BX=0000 CX=002D DX=0000 SP=0064 BP=0000 SI=0000 DI=0000
DS=16BD ES=16AD SS=16C0 CS=16BE IP=0000 NV UP EI PL NZ NA PO NC
16BE:0000 B8BD16 MOV AX,16BD
比较它们的结果可知:
① 段寄存器CS,DS,ES和SS被置于*存储空间的底部,但不同机器,不同环境,其值不同。
② 寄存器AX,DX,BP,SI和DI置为0,BX和CX视具体情况而定。当启动DEBUG过程中包含了文件标识符时,则BX和CX的内容代表装入被调试程序的文件大小,如被调试的程序文件小于64K,则CX值为代表文件的字节数,如大于64K,则除CX外,和BX一起代表被调试的程序字节数(高位部分在BX中)。如启动时不包含文件标识符,则BX,CX为0。
③ IP和SP的值不同。
④ 各标志位如R命令的显示结果。
1.5.2 DEBUG 的主要命令
1) DEBUG命令的有关规定
①DEBUG命令都是一个英文字母,后面跟着一个或多个有关参数,多个操作参数之间用“,”或空格隔开。
②DEBUG命令必须接着按ENTER键,命令才有效。
③参数中不论是地址还是数据,均用十六进制数表示,但十六进制数据后面不要用“H”。
④可以用CTRL+BREAK键来停上个命令的执行,返回到DEBUG的提示符“-”下。
⑤用CTRL+Num LOCK键中止正在上卷的输出行,再通过按任意键继续输出信息。
2) DEBUG命令
(1) 汇编命令A
格式:a. A[段寄存器名]:[偏移地址]
b. A[段地址]:[偏移地址]
c. A[偏移地址]
d. A
功能:用该命令可将汇编语言程序直接汇编进入内存。当键入A命令后,显示段地址和偏移地址等待用户键入下一条汇编指令,每键入一条汇编指令回车后,自动显示下一条指令的段地址和偏移地址,再键入下一条汇编指令,直到汇编语言程序全部键入,又显示下一条地址时,可直接键入回车返回到提示符“-”为止。
若输入语句有错误,DEBUG就显示:
^ ERROR
且重新显示现行的汇编地址,等待新的输入。
其中a的段地址在段地址寄存器中,因此使用该命令时必须将段地址寄存器送入段地址,c的段地址在CS中,d的段地址在DS中,偏移地址为0100H。
汇编命令的主要优点是可以对部分程序进行汇编,然后进行和调试,这比放在整个程序中调试要简单便得多。
-a 10↙
168C:0010 MOV DX,[10AA]
168C:0014 MOV AX,DX
168C:0016 AND AX,000F
168C:0019
从CS:10开始,输入3条指令语句,将其汇编后,目标代码存入原地址。
在地址后直接回车键,则返回DEBUG。
在输入汇编语言语句时,应注意以下语法规则:
① 输入数值,全为16进制数,可以输入1-4个数字节字符。
② 段超越助记符为CS: ,DS: ,ES: 和SS: 。
③ A命令能自动汇编短、近、远程的转移和调用。这取决于到达目的地址的字节偏移量。可以用NEAR和FAR前缀来超越。
例如:
0100:0500 JMP 520 ;两字节短转移指令
0100:0502 JMP NEAR 505 ;三字节近转移指令
0100:0505 JMP FAR 50A ;五字节远转移指令
④ DEBUG不能区别操作数究竟是立即数还是存储单元地址,所以必须把存储单元地址放在方括弧里来加以区别。
⑤ 两个最常用的伪指令DB和DW也可以使用,用来直接将字节和字的值送入相应的存储单元中。
(2) 显示内存命令D
格式:a. D[地址]
b. D[地址范围]
c. D
功能:显示指定内存范围的内容
显示内存内容三部分:左边是地址部分,表示此行的首地址(段:偏移量);中间是存储器内容的以16进制数表示部分,以两位16进制数字表示一存储单元内容;右边是存储器内容的ASCII码部分,各字节以ASCII字符形式显示,不可显示的字符以圆点(. )表示。
例1 命令中指定了地址,则从指定地址开始,显示40H(128)字节。
-d 50↙
168C:0050 CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20 .!............
168C:0060 20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20 .....
168C:0070 20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00 ........
168C:0080 00 0D 65 78 61 6D 2E 65-78 65 00 00 00 00 00 00 ..exam.exe......
168C:0090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
168C:00A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
168C:00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
168C:00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
例2 命令中指定了地址范围,则显示该范围内内存单元的内容。
在范围中包含起始地址和结束地址。若输入的起始地址中,未含段地址部分,则D命令认为段地址在DS中。输入的结束地址中只允许有偏移量。
-d cs:10 1f↙
168C:0010 11 10 17 03 11 10 3C 0E-01 01 01 00 02 FF FF FF ......<..........
例3 命令中没有指定地址,则从上一个D命令所显示的最后一个单元的下一个单元开始,显示80H(128)字节。若以前没有使用过D命令,则从DEBUG初始化时的段和偏移量的地址开始。
-d
168C:0100 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
168C:0110 4D 00 00 0E 00 89 55 14-C6 45 1F 00 34 00 78 16 M....U..E..4.{.
168C:0120 54 4D 50 3D 43 3A 5C 57-49 4E 44 4F 57 49 4E 44 TMP=C:/WINDOWS/T
168C:0130 45 4D 50 00 54 45 4D 50-3D 43 3A 5C 57 49 4E 44 EMP.TEMP=C:/WIND
168C:0140 4F 57 53 5C 54 45 4D 50-00 50 52 4F 4D 50 54 3D PWS/TEMP.PROMPT=
168C:0150 24 70 24 67 00 77 69 6E-62 6F 6F 74 64 69 72 3D $p$g.winbotdir=
168C:0160 43 3A 5C 47 49 4E 44 4F-57 53 00 50 41 54 48 3D C:/WINDOWS.PATH=
168C:0160 43 3A 5C 47 49 4E 44 4F-57 53 3B 43 3A 5C 57 49 C:/WINSOWS;C:/WI
(3) 修改存储单元内容命令E
格式:a.E[地址][内容表]
b.E[地址]
功能:a.用命令所给定的内容表去代替指定地址范围的内存单元内容。
b.一个单元一个单元地连续修改单元内容。
其中:内容表为一个十六进制或一串十六进制数,也可以是用单引号括起的一串字符。
例1 用命令中给定的内容表替换指定范围内存单元内容。
-e cs:e2 a b c d e f↙
-d cs:e0 ef↙
168C:00E0 00 00 0A 0B 0C 0D 0E 0F-00 00 00 00 00 00 00 00 ................
CS:E2 开始的6个单元呢荣改成A、B、C、D、E、F。
例2 用格式b,屏幕上显示指定单元的地址和内容,用下面的操作方法,逐个单元进行修改。
① 输入一个字节16进制数后,按空格键,以代替原单元中的内容。然后再显示下一单元的地址和内容。若还要修改的话,则输入一个字节16进制数,再按空格键……这样就可以连续不断地修改。
② 若某一单元的内容不需要修改,而操作又要往下进行,则可直接空格键。
③ 输入一个连接号(-),则显示前一单元地址和内容,若要修改的话,则输入新值,然后再按(-),这样就可以实现反向逐步修改。
若显示的前一个单元的内容不需要修改,可直接按(-)键。
④ 按Enter键,以结束E命令返回DEBUG。
-e cs:e2↙
168C:00E2 0a.01 0b.02 0c.03 0d.04 0e.05 0f.06
-d cs:20 2f↙
10FA:0020 00 00 01 02 03 04 05 06-00 00 00 00 00 00 00 00 ................
将例1修改的内容又修改为1,2,3,4,5,6。
⑤ 检查和修改寄存器内容命令R
格式:a. R
b. R [寄存器]
c. R F
功能:a. 显示CPU内部所有寄存器的内容和全部标志位的状态。
b. 显示和修改一个指定寄存器的内容。
c. 显示和修改标志位的状态。
例1 显示所有16位寄存器的内容,以及用字母表示标志位状态和将要执行的下条指令。
-r↙
AX=0000 BX=0000 CX=002D DX=0000 SP=0064 BP=0000 SI=0000 DI=0000
DS=16AD ES=16AD SS=16C0 CS=16BE IP=0000 NV UP EI PL NZ NA PO NC
16BE:0000 B8BE16 MOV AX,16BD
前两行显示各16位寄存器内容和双字母表示的标志位状态。最后一行批示将要执行的下条指令的地址和指令码及其反汇编格式。这是由CS:IP批示的指令。
例2显示单个16位寄存器内容,并可进行修改。
-r ax ↙
则屏幕显示:
AX 0000
:
如不需要修改,则按Enter键。如果修改,则在冒(:)后输入两个字节的16进制数,再按Enetr健。
又如:
-r cx↙
CX 002D
:00FF
-r cx ↙
CX 00FF
:002D
-r cx↙
CX 002D
:
将寄存器CX内容从002D改为00FF,又改回002D。
例3 显示8个标志位状态,并可修改其中之一或全部。
-rf↙
则屏幕显示:
NV UP EI PL NZ NA PO NC –
若不需要修改任何标志位,则直接按Enter键。若需要修改标志,则可输入标志的相反值,且与输入标志的顺序无关,标志间也可不用空格,最后按Enter键。
又如:
-rf ↙
NV UP EI PL NZ NA PO NC –di OV
-rf↙
OV UP DI PL NZ NA PO NC –ei NV
-rf↙
NV UP EI PL NZ NA PO NC –
标志位NV、EI改为OV、DI,后又改为NV、EI。
表1.3给出了各标志位置位、复位状况。
(5) 反汇编命令U
格式:a. U[地址]
b. U[地址范围]
功能:将指定范围内的代码以汇编语言形式显示,同时显示该代码位于内存的地址和机器码。
表1.3 标志位
标志位 |
置位 |
复位 |
溢出Overflow(YES/NO) |
OV |
NV |
方向Direction(增量/减量) |
DN |
UP |
中断(允许/屏蔽) |
EI |
DI |
符号(正/负) |
NG |
PL |
零Zero(Yes/No) |
ZR |
NZ |
辅助进位Auxiliary Carry(Yes/No) |
AC |
NA |
奇偶Parity(奇/偶) |
PE |
PO |
进位Carry(Yes/No) |
CY |
NC |
若命令中没有指定地址则以前一个U命令反汇编最后一条指令的后面一个单元为起始地址。若先前没有使用过U 命令,则开始地址以DEBUG初始化段寄存器的值作为段地址,0100H作为偏移地址。
将前面用A命令汇编过的3条语句再反汇编回来。
-u 10 16↙
168C:0010 8B16AA10 MOV DX[10AA]
168C:0014 8900 MOV AX,DX
168C:0016 250F00 AND AX,000F
反汇编字节数取决于系统显示格式及反汇编命令的选择方式。一般,反汇编和显示的字节数可能比要求的或默认的数量要多一些,这是因为各指令有不同的长度,为了对最后一条指令反汇编,就可能包括比要求多一点的字节。类似原因,要保证命令中的起始地址必须是指令码的首字节,否则反汇编会出错。
若只输入偏移量作为起始地址,则隐含CS作为段寄存器。
(6) 追踪与显示命令T
格式:a. T[=地址]或T[地址]
b. T[=地址][条数]或T[地址][条数]
功能:a. 执行一条指定地址处的指令,停下来,显示CPU所有寄存器内容和全部标志位的状态,以及下一条指令的地址和内容。
b. 为多条跟踪命令,从指定地址开始,若命令中用[地址]给定了起始地址,则从起始地址开始:若未给定,则从当前地址(CS:IP)开始,执行命令中的[条数]决定一共跟踪几条指令后返回DEBUG状态。
例1 按单条指令跟踪。
-t↙
AX=168D BX=0000 CX=002D DX=0000 SP=0064 BP=0000 SI=0000 DI=0000
DS=16AD ES=16AD SS=17C0 CS=16BE IP=0003 NV UP EI PL NZ NA PO NC
16BE:0003 8ED8 MOV DS,AX
-t=03↙
AX=16BD BX=0000 CX=002D DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=16BD ES=16AD SS=16C0 CS=16BE IP=0005 NV UP EI PL NZ NA PO NC
16BE:0005 BB0000 MOV BX,0000
例2 按多条指令跟踪
由跟踪命令产生连续显示,一直执行到Value条指令为止。因此,在执行多条跟踪指令时,可以在任何时候按Ctrl-Numlock或pause暂停显示滚动。当需要继续跟踪显示时,再按任一其他字符键又可快速显示滚动。
-t=03 5↙
AX=16BD BX=0000 CX=002D DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=16BD ES=16AD SS=16C0 CS=16BE IP=0005 NV UP EI PL NZ NA PO NC
16BE:0005 BB0000 MOV BX,0000
AX=16BD BX=0000 CX=002D DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=168E ES=16AD SS=16C0 CS=16BE IP=0008 NV UP EI PL NZ NA PO NC
16BE:0005 B10A MOV CL,0A
AX=16BD BX=0000 CX=000A DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=168E ES=16AD SS=16C0 CS=16BE IP=000A NV UP EI PL NZ NA PO NC
16BE:000A C60730 MOV BYTE PTR[BX],30 DS:0000=00
AX=16BD BX=0000 CX=000A DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=168E ES=16AD SS=16C0 CS=16BE IP=000D NV UP EI PL NZ NA PO NC
16BE:000D 43 INC BX
AX=16BD BX=0000 CX=002D DX=0000 SP=0062 BP=0000 SI=0000 DI=0000
DS=168E ES=16AD SS=16C0 CS=16BE IP=000E NV UP EI PL NZ NA PO NC
16BE:000E FEC9 DEC CL
T命令用于程序调试,能跟踪程序执行情况,迅速找出错误原因。
(7) 运行命令G
格式:G[=地址][地址][地址…]
功能:执行用户正在调试的程序。
其中:地址为执行起始地址,以CS中内容作为段地址,以等号后面的地址为偏移地址,再后面的地址为断点地址。在命令行中只有起始地址,没有断点地址,则程序在执行时不中断。
例1 没有断点的运行。
-g ↙
0000000000
Program terminated normally
-
又如:
-g=05↙
0000000000
Program terminated normally
-
当每次用不同的地址去检查程序的执行情况时,这种选择是很有用的。如果不使用[=地址]参数,则在发出G命令之前,必须将CS:IP的值先设置正确。
当程序执行完毕,DEBUG显示信息“program terminated normally”(程序正常结束)。若还要执行此程序,则必须重新将程序输入。
命令中的地址参数所指的单元,要保证包含有效的指令码,若指定的地址单元不包含有效指令的第一个字节,将会产生死机现象。
例2 设置断点的运行。
-g=03 0d↙
AX=0000 BX=0000 CX=000A DX=0000 SP=0064 BP=0000 SI=0000 DI=0000
DS=0000 ES=16AD SS=16C0 CS=16BE IP=000D NV UP EI PL NZ NA PO NC
16BE:000D 43 INC BX
在CS:0D处设了断点,程序运行到此停止。
在调试程序时,往往要设置断点。DEBUG程序允许最多设置10个断点,这些断点地址的次序是任意的。设置多断点的目的是:可以逐段地检查程序的执行,特别是程序为多分支时,则不管程序走哪个分支,均可在分支中的断点处停止执行,以检查程序是否正确。
DEBUG程序的断点设置是用一个中断类型3指令(操作码为CCH)来代替被调试程序在断点地址处的操作码。当程序执行到一个断点地址时,就停下来,显示CPU各寄存器的内容和各标志位状态,以及下一条要执行的指令:且被调试程序的所有断点处的指令码都被除数恢复,全部断点被取消,并返回DEBUG。
若输入的断点地址只包含地址的偏移量,则G命令认为其段地址隐含在段寄存器CS中。
(8)命名命令N
格式:N文件名
功能:在调用DEBUG时,没有文件名,则需要用N命令将要调用的文件名格式化到CS:5CH的文件控制块中,才能用L命令把它调入内存进行调试。
例如:用N命令,调入EXAM.EXE文件。
C:/ASM>DEBUG↙
-N EXAM.EXE↙
-L↙
(9)读盘命令L
格式:a. L[地址][驱动器号][起始扇区号][所读扇区个数]
b. L[地址]
c. L
功能:a.把指定驱动器和指定扇区范围的内容读支指定内在的连续单元中。其中地址是读入内在的起始地址,地址缺省值为CS:100H。起始扇区号指逻辑区号的起始位置。所读扇区个数是指从起始扇区号开始读到内在几个扇区的内容,驱动器号为0或1,0表示A盘,1表示B盘。
b.读入已在CS:5CH中格式化的文件控制块指定的文件。在使用该命令前用N命令命名即可,将要读入的文件名格式化到CS:5CH的文件控制中,其中地址为内存地址。
c.同b,地址隐含在CS:100H中。当读入的文件有扩展名.COM或.EXE,则始终装入CS:100H中,命令中即使指定了地址也不起作用。
其中:BX和CX中存放所读文件的字节数。
(10)写盘命令W
格式:a. W[地址][驱动器号][起始扇区号][所写扇区个数]
b. W[地址]
c. W
功能:a. 把在DEBUG状态下调试的程序或数据写入指定的驱动器中,起始扇区号为逻辑区号,所写扇区个数为要占盘中几个扇区。
写盘指定扇区的操作应十分小心,如有差错将会破坏盘上原有的内容。
如果在命令行中的地址只包含偏移地址,W命令认为段地址在CS中。
b. 当键入不带参数的写盘命令时(或只键入地址参数的写盘命令),写盘命令把文件写到软盘上。该文件在用W命令之前用命令N将文件格式化在CS:5CH的文件控制块中。
c. 只有W命令而没有任何参数时,与N配合使用进行写盘操作。
在用W命令以前在BX或CX中应写入文件的字节数。
(11) 结束DEBUG返回DOS命令Q。
格式:Q
功能:程序调试完退出DEBUG状态,返回到DOS状态下。
Q命令不能把内存的文件存盘,要想存盘必须在退出DEBUG之前用W命令写盘。
第二章 汇编语言程序实训
实训一 顺序程序设计
实训目的
(1)掌握顺序程序设计方法。
(2)学习数据传送及算术和逻辑运算指令的用法。
(3)熟悉在PC机上建立、汇编、连接、调试和运行8086汇编程序的过程。
实训内容
(1)有一字变量BUF1是以原码表示的有符号数,要求将其转换为反码和补码,分别存入BUF2各BUF3单元,并在屏幕上显示出来。
(2)有两个两字节无符号数分别在存储单元A、B起始的缓冲器中,求其和,结果放在A起始的缓冲区并在屏幕上显示。相加若有进位不存入存储单元。
实训设备
PC机一台。
实训准备
(1)分析题目,将程序中的原始数据和最终结果的存取方法确定好。
(2)画出流程图。
(3)写出源程序。
(4)对程序中的结果进行分析,并准备好上的调试与汇编程序及汇编调试的过程。
实训步骤
(1)输入源程序。
(2)汇编、连接程序,生成。EXE文件,执行文件,检查结果。
实训报告的要求
(1)列出源程序,说明程序的基本结构,包括程序中各部分的功能。
(2)说明程序中各部分所用的算法。
(3)说明主要符号和所用到寄存器的功能。
(4)上机调试过程中遇到的问题是如何解决的。
(5)对调试源程序的结果进行分析。
实训二 循环程序设计
实训目的
(1)加深对循环结构的理解。
(2)掌握循环程序的设计方法。
(3)熟练掌握DEBUG的常用命令,学会以用DEBUG调试程序员。
实训内容
(1)编制程序计算S=1+2*3+3*4+4*5+……+N(N+1)+……直到N(N+1)大于200为止,并使结果显示在屏幕上。其程序的逻辑框图如图所示。
开始 |
1→DX,2→BL |
BL→AL,BL+1→BL |
AX>200 |
AL*BL→AX,DX+AX→DX |
显示 |
N |
Y |
开始 |
(2)将从3000H内存单元开始的100个字节存储单元全部清零。
本实训要求在DEBUG调试状态下进行,包括汇编程序、运行程序、检查结果。
实训设备
PC机一台
实训步骤
实训内容一:
(1)按程序流程图编制实训程序。
(2)输入源程序。
(3)汇编、连接程序,执行程序,检查结果。
实训内容二:
(1)输入源程序并检查无误。
(2)对内存单元3000H开始的100个存储单元用E命令输入任意数。
(3)程序的执行可用DEBUG的G命令,也可用T命令单步跟踪执行。
(4)用D命令检查执行结果。
实训报告的要求
(1)列出源程序。
(2)对程序中用到的寄存器说明其功能。
(3)总结计数控制循环程序的设计方法。
(4)说明使用DEBUG进行程序调试的方法,调试过程中所遇到的问题是如何解决的。
实训三 分支程序设计
实训目的
(1)掌握分支程序的结构。
(2)掌握分支程序的设计、调试方法。
实训内容
(1)在BUP和BUP+1、BUP+2单元分别放有一个无符号字节型数,编程序将其中最大数存入MAX单元,并在屏幕上显示。
(2)要求同上,只是比较的数为有符号数。
(3)将1000H单元开始的10个字节数采用奇偶校验,将奇数在前偶数在后仍存回原数据区,本实训要求在DEBUG调试状态下进行,包括汇编程序、运行程序、检查结果。
实训准备
(1)阅读教材中有关分支程序的内容。
(2)按要求编写程序。
(3)对照实训步骤,将要测的数据事先画好表格。
实训设备
PC机一台
实训步骤
(1)输入源程序
(2)汇编、连接程序,生成。EXE文件,执行文件检查结果。
(3)对于实训内容三,进入DEBUG后,先用A命令汇编程序,同时用E命令对1000H开始的单元置10个字节数,然后对程序进行调试,用T命令观察程序流程。程序运行完毕用D命令检查1000H开始的10个单元的内容。
实训报告的要求
(1)列出源程序
(2)将实训测得的数据与理论分析比较。
(3)总结为什么在设计分支程序时必须解决三个问题判断、转向各定标号。
(4)说明标志位CF,SF和OF的意义。
实训四 子程序设计
实训目的
(1)学习子程序的定义和调用方法。
(2)掌握子程序、子程序的嵌套、递归子程序的结构。
(3)掌握子程序设计、编制及调试。
实训内容
设有五个字数据存放在以BUP为首地址的内存单元中,要求采用调用多个字数据相加的子程序方法编程,和的低位字放在RESULT单元,和的高位字放在RESULT+2单元,并将结果显示在屏幕上。
实训准备
(1)阅读教材中有关的内容,按要求编写程序。
(2)熟悉字符显示程序段的编写。
(3)对照实训步骤,将要测的数据画好表格。
实训设备
PC机一台。
一、实训步骤
(1)编辑、汇编、连接程序,生成。EXE文件。
(2)进入DEBUG,对程序进行调试。
在以BUF为起始地址的存储区中置入数据。
调试运行程序,记录RESULT和RESULT+2单元的内容。
实训报告的要求
(1)列出源程序。
(2)通过实训说明PUSH指令和POP指令的功能及先进后出的工作原理。说明子程序开始用PUSH指令保护现场,执行完子程序主体后用POP指令恢复现场的必要性。
(3)说明主程序和了程序在程序形式上有何异同
实训五 显示程序设计
实训目的
(1)掌握软件延时程序的编写方法。
(2)熟悉系统功能调用的方法。
(3)掌握宏定义与宏调用的方法。
实训内容
(1)在CRT上每隔一秒连续显示字符0-9。
编程提示:
为了使输出的字符之间有空格,在每一个循环中输出一个0-9的字符和一个空格。为了输出0-9,置寄存器BL初值为0,每循环一次使其增量。为了保证输出是十进制,增量后用DAA调整指令。由于输出为一位十进制数,用AND 0FH指令屏蔽高4位。
(2)用系统功能调用将‘HELLO’由键盘输入,再从屏幕输出‘***HELLO***’。
实训设备
PC机一台。
实训步骤
(1)输入源程序。
(2)编辑、汇编、连接程序,生成。EXE文件,执行文件检查结果。
(3)改变延时时间,观察显示速度。
实训报告的要求
(1)列出源程序。
(2)总结软件延时程序的编写方法。
(3)总结常用系统调用的功能及调用方法。
实训参考程序:
实训1 EXAM1-1
DATA SEGMENT
BUF1 DW 9348H
BUF2 DW 4DUP(0),0AH,0DH,’$’
BUF3 DW 4DUP(0), ’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN: MOV AX,DATA
MOV DS,AX
MOV AX,BUF1
ADD AX,0
JS NEXT
MOV BUF2,AX
MOV BUF3,AX
JMP EEE
NEXT: AND AX,7FFFH
NOT AX
MOV BUF2,AX
INC AX
MOV BUF3,AX
EEE: MOV CX,0004H
MOV DI,OFFSET BUF2
MOV DX,[DI]
ADD DI,03
BBB: MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB QQQ
ADD AL,07H
QQQ: ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04H
SHR DX,CL
POP CX
LOOP BBB
MOV CX,0004H
MOV SI,OFFSET BUF3
MOV DX,[SI]
ADD SI,03H
CCC: MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB DDD
ADD AL,07H
DDD: ADD AL,30H
MOV [SI],AL
DEC SI
PUSH CX
MOV CL,04H
SHR DX,CL
POP CX
LOOP CCC
MOV DX,OFFSET BUF2
MOV AH,09H
INT 21H
MOV DX,OFFSET BUF3
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
执行程序EXAM1-1。EXE,屏幕上显示结果:
ECB7
ECB8
实训1 EXAM1-2
DATA SEGMENT
A DB 34H,18H,2DUP(0),’$’
B DB 56H,83H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV AL,A
MOV BL,B
ADD AL,BL
MOV AH,A+1
MOV BH,B+1
ADC AH,BH
MOV A,AL
MOV A+1,AH
MOV CX,0004H
MOV DI,OFFSET A
MOV DX,[DI]
ADD DI,03
NEXT: MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB QQQ
ADD AL,07H
QQQ: ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04
SHR DX,CL
POP CX
LOOP NEXT
MOV DX,OFFSET A
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
执行程序EXAM1-2。EXE,屏幕上显示结果:
9B8A
实训2 EXAM2-1
DATA SEGMENT
BUF DB’S=1+2*3+3*4+4*5+。。。。。。+N(N+1)+。。。=’,’$’
RES DW 4 DUP(0),’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF
MOV AH,09H
INT 21H
MOV DX,1
MOV BL,2
NEXT: MOV AL,BL
INC BL
MUL BL
ADD DX,AX
CMP AX,200
JNA NEXT
MOV CX,0004H
MOV DI,OFFSET RES
ADD DI,03H
NEXT1:MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB NEXT2
ADD AL,07
NEXT2:ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04
SHR DX,CL
POP CX
LOOP NEXT1
MOV DX,OFFSET RES
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
执行程序EXAM2-1。EXE,屏幕上显示结果:
S=1+2*3+3*4+4*5+。。。。。。+N(N+1)+。。。=045F
实训2 EXAM2-2
ORG 2000H
2000 BF0030 MOV DI,3000
2003 B164 MOV CL,64
2005 C60500 MOV BYTE PTR[DI],0
2008 47 INC DI
2009 FEC9 DEC CL
200B 75F8 JNZ 2005
200D F4 HLT
实训3 EXAM3-1
STACK SEGMENT STACK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DB 70H,35H,1FH
MAX DB 2 DUP(?),’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN:MOV AX,DATA
MOV DS,AX
MOV AL,BUF
CMP AL,BUF+1
JNB LP1
MOV AL,BUF+1
LP1: CMP AL,BUF+2
JMB LP2
MOV AL,BUF+2
LP2: MOV CX,02H
MOV DI,OFFSET MAX
MOV DL,AL
INC DI
LP3: AND AL,0FH
CMP AL,0AH
JB LP4
ADD AL,07H
LP4: ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04
SHR DL,CL
POP CX
MOV AL,DL
LOOP LP3
MOV DX,OFFSET MAX
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
执行程序EXAM3-1。EXE,屏幕上显示结果:
70
实训3 EXAM3-2
STACK SEGMENT STACK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DB 98H,75H,32H
MAX DB 2 DUP(?),’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN: MOV AX,DATA
MOV DS,AX
MOV AL,BUF
CMP AL,BUF+1
JG LP1
XCHG AL,BUF+1
LP1: CMP AL,BUF+2
JG LP2
XCHG AL,BUF+2
LP2: MOV MAX,AL
MOV CX,02H
MOV DI,OFFSET MAX
MOV DL,[DI]
INC DI
LP3: MOV AL,DL
AND AL,0FH
CMP AL,0AH
JB LP4
ADD AL,07H
LP4: ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04
SHR DX,CL
POP CX
LOOP LP3
MOV DX,OFFSET MAX
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
执行程序EXAM3-2。EXE,屏幕上显示结果:
75
实训3 EXAM3-3
ORG 2000H
2000 BE0010 MOV SI,1000
2003 BF0910 MOV DI,1009
2006 8A14 MOV DL,[SI]
2008 80C200 ADD DL,00
200B 7B0B JPO 2018
200D 8615 XCHG DL,[DI]
200F 8814 MOV [SI],DL
2011 4F DEC DI
2012 39FE CMP SI,DI
2014 7407 JE 201D
2016 EBF0 JMP 2008-03-15
2018 46 INC SI
2019 8A14 MOV DL,[SI]
201B EBF5 JMP 2012
201D F4 HLT
实训4 EXAM4-1
STACK SEGMENT STACK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DW 0F101H,110DH,52H,100H,456H
COUNT =($-BUF)/2
RESULT DW 4 DUP(?),’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
WDADD PROC
PUSH DI
MOV AX,0
MOV DX,0
MOV DI,OFFSET BUF
NEXT2: ADD AX,[DI]
JNC NEXT1
INC DX
NEXT1: ADD DI,2
LOOP NEXT2
POP DI
RET
WDADD ENDP
SHOW PROC
PUSH CX
PUSH DI
MOV CX,04H
MOV DI,OFFSET RESULT
MOV BX,AX
ADD DI, 07H
BBB: MOV AX, BX
AND AX,000FH
CMP AL,0AH
JB QQQ
ADD AL,07H
QQQ: ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04
SHR BX,CL
POP CX
LOOP BBB
MOV CX,0004H
CCC:MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB DDD
ADD AL,07H
DDD:ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04H
SHR DX,CL
POP CX
LOOP CCC
POP DI
POP CX
RET
SHOW ENDP
BEGIN:MOV AX,DATA
MOV DS,AX
MOV CX,COUNT
CALL WDADD
CALL SHOW
MOV DX,OFFSET RESULT
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
执行程序EXAM42-1。EXE,屏幕上显示结果:
000107B6
实训4 EXAM4-2
SSEG SEGMENT STACK
DB 1024 DUP(0)
SSEG ENDS
DATA SEGMENT
BUFO DB 6 DUP(/),’$’
ARRA DW -1,75,9,-289,300,-27,32,77,1000,45
CDUNT EQU $-ARRA
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:SSEG
DABC PROC
CMP AX,0
JGE ET
NEG AX
ET: RET
DABC ENDP
DISPS PROC
PUSH DX
PUSH AX
MOV DX,DI
MOV AH,09H
INT 21H
MOV DL,’,’
MOV AH,02H
INT 21H
POP AX
POP DX
RET
DISPS ENDP
DATCH PROC FAR
PUSH DX
PUSH CX
PUSH BX
MOV CX,10
MOV BX,AX
CALL DABC
DLOP1:DEC DI
XOR DX,DX
DIV CX
OR DL,30H
MOV [DI],DL
CMP AX,0
JNZ DLOP1
CMP BX,0
JNZ DLOP1
CMP BX,0
JGE DEXIT
DEC DI
MOV BYTE PTR[DI],
DEXIT:POP BX
POP CX
POP DX
RET
DATCH ENDP
BEGIN:MOV AX,DATA
MOV DS, AX
MOV DX, CONUT/2
LPO1: DEC DX
MOV CX, DX
MOV BX, DX
MOV SI, COUNT-2
LOP2: MOV AX, ARRA[SI]
CMP AX, ARRA[SI-2]
JGE PASS
XCHG ARRA[SI-2], AX
MOV ARRA[SI], AX
MOV BX, CX
PASS: SUB SI, 2
LOOP LOP2
CMP BX, DX
JE DLAST
JMP LOP1
DLAST: MOV CX, COUNT/2
LEA SI, ARRA
LOP3: MOV AX, [SI]
MOV DI, OFFSET BUFO
ADD DI, LENGTH BUFO
CALL DATCH
CALL DISPS
ADD SI, 2
LOOP LOP3
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN
执行程EXAM4-2。EXE, 序屏幕上显示结果:
-289, -27, -1, 9, 32, 45, 75, 77, 300, 10000,
实训 5 EXAM5-1
STACK SEGMENT STACK
DB 1024 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS: CODE, SS: STACK
START: MOV BL, 0
LP: MOV DL, 20H
MOV AH, 2
INT 21H
MOV AL, BL
ADD AL, 0
DAA
AND AL, 0FH
MOV BL, AL
PUSH BX
OR AL, 30H
MOV DL, AL
MOV AH, 2
INT 21H
MOV BX, 3E8H
MOV BX, 3E8H
LP2: MOV CX, 176H;延时1ms
LP1: PUSHF
POPF
LOOP LP1
DEC BX
JNZ LP2
POP BX
INC BL
JMP LP
CODE ENDS
END START
执行程序EXAM5-1。EXE, 屏幕上依次循环显示一个数字一个空格:
0 1 2 3 4 5 6 7 8 9 、、、
实训5 EXAM5 – 2
STACK SEGMENT SATCK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUFF DB 6, 7 DUP(?), ’$’
DATA ENDS
INPUT MACRO BUFE
MOV DX, OFFSET BUFE
MOV AH, 0AH
INT 21H
ENDM
PUTCHAR MARCO CHAR
MOV DL, CHAR
MOV AH, 02H
INT 21H
ENDM
CODE SEGMENT
ASSUMENT CS: CODE, DS: DATA, SS: STACK
START: MOV AX, DATA
MOV DS, AX
INPUT BUFF ;读取字符串 BUFF
PUTCHAR 0DH
PUTCHAR 0AH ;光标另起一行
MOV CX, 0003H
NEXT: PUTCHAR 2AH
LOOPNEXT
MOV CL, BUFF+1
SUB CH, CH
MOV BX, OFFSET BUFF+2
BEGIN: MOV AL, [BX]
PUTCHAR AL
INC BX
LOOP BEGIN
MOV CX, 0003H
NEXR1: PUTCHAR 2AH
LOOP NEXT1
MOV AH, 4CH
INT 21H
CODE ENDS
END START
执行程序EXAM5-2。EXE, 输入HELLO 屏幕上会显示结果:
***HELLO***