1、计算机硬件技术基础实验指导书V13计算机硬件技术基础实验指导书东北大学计算中心二零一零年四月 目录第1章 汇编语言程序设计基础 11.1 汇编语言程序的语句 11.1.1 语句格式 11.1.2 数据定义 11.2 汇编语言程序的结构 21.3 汇编语言常用伪指令 3第2章 汇编语言程序调试过程 62.1 汇编语言程序的命令行开发调试过程 62.1.1 编辑源程序 62.1.2 汇编程序 82.1.3 连接程序 102.1.4 调试程序 112.2 汇编语言编程集成开发环境PWB 182.2.1 编辑源文件 192.2.2 运行程序 20第3章 汇编语言程序设计实验 293.1 顺序程序设计
2、293.2 分支程序设计 313.3 循环程序设计 353.4 综合程序设计 37第4章 实验报告撰写规范 42附录 45I ASCII码表 45II 指令速查表 46III 伪指令表 50IV DOS功能调用 51V 常用BIOS功能调用 56VI 错误码表 58第1章 汇编语言程序设计基础1.1 汇编语言程序的语句1.1.1 语句格式汇编与言语句一般是由分隔符分成的四个部分组成,格式如下:名字 助记符 操作数 ;注释其中带方括号的项可以省略。名字项是合法的标识符,包括标号、变量名、过程名、段名或符号名等。其中,标号后要跟冒号(:),用于指令之前,表示指令的起始地址。标识符由字母、数字以及_
3、、$、?和组成,并满足如下要求:(1) 不能以数字开头;(2) 不能单独使用或,它们有专门用途;(3) 不能是系统的保留字,如指令名、寄存器名和伪指令名等。(4) 一个名字的最大有效长度为31,超过31的部分计算机不再识别。为了便于记忆,名字的定义最好能够见名知义,如用BUFFER表示缓冲区,SUB表示累加和等。助记符项可以是指令或伪指令。操作数项包含0个、一个或多个操作数,依赖于具体的指令或伪指令。多个操作数之间以逗号(,)分隔。注释项以分号(;)开始。汇编语言源程序中的每条语句一般占一行,每行不超过132个字符(MASM6.0开始可以是512个字符),汇编语言对大小写是不敏感的。为了使程序
4、具有较好的可读性,应该使各个项对齐。通常将名字项放在第一列,后面的几项依次以一个或多个TAB分隔。1.1.2 数据定义 通过数据定义语句可为数据项分配存储单元,并根据需要设置其初值。还可用符号代表数据项,此时符号就与分配的存储单元相联系。代表数据项的符号本身称为变量名,与之相对应的存储单元用于存放变量,所以常常就把这样的存储单元称为变量。例1.1 定义字节数据COUNT DB 100 ;定义一个字节的存储空间,存放100BUFF DB 3+4,5*6 ;定义两个字节的存储空间,存放7,30例1.2 定义字数据FLAG1 DW 65530 ;定义一个字存储空间,存放65530FLAG2 DW 0
5、F020H ;定义一个字存储空间,存放0F020H例1.3 定义没有初值的数据项BUF 1 DW ?,? ;定义两个字存储空间,没有定义初值例1.4 定义字符串MESS1 DB “HELLO!” ;定义一个字符串,内容是HELLO!MESS2 DB H,E,L,L,O,! ;定义一个字符串,内容是HELLO!例1.5 重复操作符DUPBUF2 DB 5 DUP(0) ;定义5个字节的存储空间,初值均为0例1.6 使用EQU定义等值表达式COUNT EQU 234 ;例1.7 使用等号定义COUNT=234 ;例1.8 使用$定义$是一个特殊的地址表达式,表示当前地址。X DW 0,1,2,4,
6、8,4,2,1,0 ;LEN DB $-X ;变量LEN的值等于181.2 汇编语言程序的结构汇编语言源程序建立在段结构的基础上,一个段就是一些指令和数据的集合。所以一个汇编语言源程序,根据程序用途被划分成几段,如数据段、堆栈段、附加段和程序段(代码段),用CS、DS、SS、ES段寄存器存放段值。这样就构造了源程序的基本格式:DATA SEGMENTDATA ENDSEXTRA SEGMENTEXTRA ENDSSTACK1 SEGMENTSTACK1 ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA ASSUME SS:STACK1,ES:EXTRASTART:
7、 MOV AX,DATA MOV DS,AXCODE ENDS END START结合上面的源程序结构格式,需要说明如下:(1) 互相配对的SEGMENT和ENDS前的标号必须一样;(2) ASSUME语言使汇编程序得知哪一段是数据段(DS),哪一段是堆栈段(SS),哪一段是附加段(ES),哪一段是代码段(CS)。除CS段以外,各个段寄存器的实际值还要用MOV指令来赋予;(3) END START表示源程序结束。下面,我们通过一个简单的汇编语言程序来说明汇编语言的结构DSEG SEGMENT ;数据段开始DATA1 DB 13H,26HDATA2 DW 0DSEG ENDS ;数据段结束SSE
8、G SEGMENT STACK ;堆栈段开始SKTOP DB 20 DUP(0)SSEG ENDS ;堆栈段结束CSEG SEGMENT ;代码段开始 ASSUME CS:CSEG,DS:DSEG ASSUME SS:SSEGSTART: MOV AX,DSEG ;初始化数据段基址 MOV DS,AX MOV AX,SSEG ;初始化代码段基址 MOV SS,AX MOV SP,LENGTH SKTOP ;设置堆栈指针 MOV AL,DATA1 ADD AL,DATA1+1 MOV BYTE PTR DATA2,AL MOV AH,4CH INT 21H ;返回DOSCSEG ENDS ;代码
9、段结束 END START ;源程序结束说明如下:(1)DSEG是用户自定义的数据段的段名,SEGMENT和ENDS分别为表示段开始和结束的伪指令。(2)SSEG是堆栈段的段名,STACK表示此段是程序运行时使用的堆栈段,连接程序要求定义一个堆栈段,若无此段,连接程序指出“无堆栈段”错误。(3)CSEG是代码段的段名,一般要先用ASSUME语句指定哪一段是数据段,哪一段是堆栈段和代码段,但是段寄存器的实际地址仍需MOV指令赋予。(4)END START说明,START为程序的启动地址,即程序从这里开始执行,而END告诉汇编程序源程序到此结束,对END后面的任何语句都不再进行汇编。1.3 汇编语
10、言常用伪指令一、表达式赋值伪指令1等值定义EQU格式:符号名 EQU 表达式说明:将右侧表达式的值或意义赋给左侧自定义的标识符号。表达式可以是各种常数、数据符号、指令助记符、伪指令助记符、寄存器名字或其它自定义标识符号。在同一个程序中,一个用EQU定义的符号不能被再定义。2等号伪指令=格式:符号名=表达式说明:作用与EQU相同,惟一的区别是等号语句可以多次被定义。二、数据定义伪指令1定义字节变量DB格式:变量名 DB 表达式,表达式说明:DB用于定义字节变量,每个表达式的值占有一个字节。字节的值域对无符号数为0255,对带符号数为128127。初值表中各项数据用逗号隔开,每项数据占一个字节单元
11、。如果处置表中的初值为“?”,则对应单元字节将不赋初值,其内容为不确定值。2定义字变量DW格式:变量名 DW 表达式,表达式说明:DW用于定义字变量。初值表中各项数据为字,占两个字节,并且字单元不仅可以存放数值,还可以存放变量的偏移地址。3定义双字变量DD格式:变量名 DD 表达式,表达式说明:DD用于定义双字变量,每个数据项占四个字节。它可以是表达式、十进制整数、字符串、“?”或是一个变量、标号的段地址和偏移地址。4定义四字变量DQ格式:变量名 DQ 表达式,表达式说明:变量为四字变量,每个元素表达式占八个字节,它可以是表达式、?、十进制实数、实数的十六进制编码及字符串。5定义十字节变量DT
12、格式:变量名 DT 表达式,表达式说明:变量为十字节变量,每个元素表达式占十个字节,它可以是表达式、?、十进制整数、BCD数及字符串。6变量重复定义子句DUP格式:重复次数 DUP(元素值)说明:重复次数取正整数,元素值可为数值表达式或“?”三、段定义伪指令1段首说明伪指令SEGMENT格式:段名 SEGMENT PRMT1PRMT2PRMT3说明:段名是用户自定义的标识符号。这个语句的作用是告诉汇编程序具有这个名字的段由此开始。PRMT分别为定位类型,组合类型,连接期间用于组或段组的名称,为任选参数。2段结束伪指令ENDS格式:段名 ENDS说明:此语句告诉汇编程序这个名字命名的段到此结束。
13、3段假定伪指令ASSUME格式:ASSUME 段寄存器名:段名,段寄存器名:段名说明:ASSUME的作用是告诉汇编程序,把源程序转换为机器代码时,各段寄存器的符号地址,以确定和检查机器指令中操作数所在的段,产生正确的机器指令代码或打印出错误信息。4代码定位伪指令ORG格式:ORG 表达式说明:此语句的作用是确定其后的数据和代码存放在相应段的起始位置。表达式的值是相对于段基址的偏移量。四、过程定义伪指令格式:过程名 PROC 类型 RET 过程名 ENDP说明:伪指令PROC和ENDP必须成对,并给出相同的过程名。过程有两种类型FAR和NEAR,如未指出,则为NEAR。五、其它伪指令1EVEN伪
14、指令格式:EVEN说明:EVEN的作用是将汇编地址计数器调整到偶地址边界,以便随后的数据或代码在偶地址边界上对准。2END伪指令格式:END STRAT说明:START为程序的启动地址。END告诉汇编程序源程序到此结束,对END后面的任何语句不再进行汇编。 第2章 汇编语言程序调试过程2.1 汇编语言程序的命令行开发调试过程一般汇编语言的上机过程是首先用某一个文本编辑器形成一个以ASM为扩展名的源程序文件,然后用汇编程序翻译源程序,将ASM文件转换为OBJ模块文件,最后用连接程序将一个或多个目标文件链接成个可执行文件。2.1.1 编辑源程序可用计算机系统中各种能编辑文本文件的编辑器来编辑汇编源
15、程序。常用的编辑器有:EDIT、记事本、UltraEdit、EditPlus等。利用这些文本编辑工具编辑源程序,生成一个汇编语言源程序的纯文本文件。汇编语言源程序文件的扩展名是:.ASM。这里介绍利用EDIT行编辑程序来编辑汇编源程序的过程。运行EDIT程序可以在Windows操作系统的命令提示符,可以有两种方法运行命令提示符,一种是从开始菜单程序附件命令提示符,如下图所示。图2.1另外一种方法是在开始运行对话框里输入cmd后回车,如下图所示。图2.2进入命令提示符界面如下。输入cd命令后改变当前目录到C盘根目录下。输入edit命令就可以进入编辑环境了。图2.3进入edit编辑环境界面如下,在
16、这里可以输入汇编源程序了。汇编语言源程序一行安排一条语句,不采用类似C或者PASCAL等高级语言源程序那样的分层次缩进格式。如下是汇编语言源程序的一般格式。请注意上下行之间的指令助记符及第一个操作数首字符的对齐,利用制表符(TAB键)能较好的实现对齐格式。图2.4输入完程序后,需要保存文件,选择FileSave命令,如下图所示。图2.5选择Save命令后出现如下对话框。在File Name:一栏里输入保存的文件名,此处为Hello.asm。输入完后选择OK。图2.6保存成功,标题栏变为刚才所输入的文件名,如下图所示。保存完毕后,选择FileExit命令退出编辑程序,返回到命令行提示符界面。图2
17、.7这样,源程序的编辑过程就完成了。需要注意的是:使用Windows的记事本编辑汇编源程序时,默认的扩展名是.TXT。在保存文件时,需要将文件扩展名修改成.ASM。2.1.2 汇编程序当源程序编写好后,利用汇编器MASM汇编源程序生成目标代码文件。通常目标代码文件的扩展名是.OBJ。汇编器还可以生成列表文件和交叉参考文件。汇编器相当于高级语言程序设计中的编译器。汇编器按汇编语言的语法检查源程序,如果源程序中有语法错误的行,那么汇编器就不生成目标代码文件,汇编程序将显示出错误位置和原因。这种情况下,必须回到第一步,重新编辑源程序,修改语法错误的行。如果源程序没有语法错误,那么,将生成目标文件(.
18、OBJ文件)。当发现源程序中的某些行含可疑成分或不确定因素时,汇编器会给出警告信息,但仍按缺省处理办法生成目标代码文件。这种情况下,可以重新编辑源程序,消除可疑成分或不确定因素。MASM是微软提供的用于对汇编源程序进行编译的程序。可以输入masm /?来查看这个命令的使用方法,如下图所示。图2.8接下来对编辑完毕后的源程序进行汇编,在命令行提示符下输入masm hello.asm命令就可以对汇编源程序编译了,如下图所示。图2.9从编译结果可以看出,在hello.asm的17行有错误,错误类型是符号STRAT没有定义。这时候需要返回edit编辑环境对源程序进行修改。因为hello.asm文件已经
19、存在,我们可以直接在命令行下输入edit hello.asm命令来修改程序。图2.10修改后保存文件,退出编辑环境。重新进行汇编,结果如下。图2.11编译通过以后,可以在hello.asm所在的目录下生成一个hello.obj的文件,这个就是编译得到的目标文件。2.1.3 连接程序当由源文件汇编成功后,即可用连接程序(LINK.EXE)生成其可执行文件。通常DOS平台上的可执行文件的扩展名是.EXE。一般单个模块的连接不会发生连接错误,总可以顺利地生成可执行文件。当多个模块连接,或者与库中的函数连接时,如果在目标代码文件或者库中找不到所需的连接信息,连接器就会发出错误提示信息,而不生成可执行程
20、序文件。这就需要修改源程序,使得汇编器生成的目标代码文件含有连接器需要的信息。这样的修改主要是对伪指令和汇编语言操作符的修改,或者是对名字符号的修改。如果出现这种情况,那么就要回到第一步编辑源程序,还要重新进行第二步汇编源程序。和masm程序一样,可以输入link /?命令来查看link程序的使用方法。输入link hello.obj命令就可以对编译生成的目标文件(hello.obj)进行连接,如下图所示。图2.12这种方法需要确认连接过程中的各种文件名,如果使用文件名的默认值,那么直接按“回车”键即可。在上面四个文件名中,最重要二个文件名是:执行文件名和库文件名。一般情况下,无需更换最终生成
21、的执行文件名;如果在连接过程中需要其它的库文件,则在显示第三行提示时,输入所需要的库文件名。连接成功后,在目标程序所在的目录下生成一个.EXE文件。可以在命令提示符下,直接输入生成的可执行文件的文件名来运行程序,如果程序正确,就可以得到预期的结果,如下图所示。图2.13技巧提示:如果不想每次连接过程中确认各种文件名,可以在文件名后面加上分号“;”,默认使用各类文件的缺省值。例如输入link hello.obj; 后回车。从MASM6.0版本开始,微软提供了一个ML.EXE程序来对汇编源程序编译和连接。其实,ML.EXE的文件名就是MASM.EXE和LINK.EXE的首字符,所以ML程序就是MA
22、SM和LINK两个程序的集成。具体使用方法如下图所示。图2.142.1.4 调试程序当程序的运行结果不是预期结果时,就需要调试程序,找出错误的语句或逻辑关系。可以使用系统调试程序DEBUG来进行调试。启动DEBUG的一般命令如下:DEBUG 文件名 参数表其中文件名指定被调试的文件,其包括名和后缀,参数表是被调试文件运行时所需要的参数。被调试的文件可以是系统中的任何文件,但通常它们的后缀为.EXE或.COM。当DEBUG启动成功后,将显示连接符“-”,这时,可输入各种DEBUG命令。如下图所示。图2.15DEBUG后可以不带文件名,仅运行DEBUG程序;需要时,再用N和L命令调人被调试程序。D
23、EBUG命令及其含义如下表所示:命令格式功能说明A地址输入汇编指令C范围 起始地址对由“范围”指定的区域与“起始地址”指定的同大小区域进行比较,显示不相同的单元D范围显示指定范围内的内存单元内容E地址 字节值表用值表中的值替换从“地址”开始的内存单元内容F范围 字节值表用指定的字节值表来填充内存区域G=起始地址 断点地址从起点(或当前地点)开始执行,到终点结束H数值1 数值2显示二个十六进制数值之和、差I端口地址从端口输入L地址 驱动器号 扇区 扇区数从磁盘读M范围 地址把“范围”内的字节值传送到从“地址”开始的单元N文件标识符 文件标识符指定文件名,为读/写文件做准备O端口地址 字节值向端口
24、输出P=地址 指令数按执行过程,但不进入子程序调用或软中断Q退出DEBUG,不保存正在调试的文件R寄存器名显示和修改寄存器内容S范围 字节值表在内存区域内搜索指定的字节值表。如果找到,显示起始地址,否则,什么也不显示T=地址 指令数跟踪执行,从起点(或当前地点)执行若干条指令U范围反汇编,显示机器码所对应的汇编指令W地址 驱动器号 扇区 扇区数向磁盘写内容,(BX、CX)为写入字节数关于参数的几点说明:1. 进制:在DEBUG中输入或显示的数据都是十六进制形式;2. 分隔:命令和参数、参数和参数之间要用空格、逗号或制表符等分隔;3. 地址:用“段值:偏移量”的形式来表示地址,也可用段寄存器来代
25、表“段值”。例如:DS:10,ES:200,CS:30等;4. 范围:用来表示地址范围,从哪个地址开始,到哪个地址结束。它有二种表示方式: 地址 地址前者表示起始地址,要用“段值:偏移量”来表达,后者表示终止地址,只用“偏移量”来表示; 地址 长度前者表示起始地址,要用“段值:偏移量”来表达,后者表示该区域的大小,用字母L开头的数值来表示;例如:100:50 100 段值为100,偏移量从50到100的内存区域;100:50 L100段值为100,偏移量从50开始的100个字节区域。5. 端口地址:二位十六进制数值;6. 字节值:二位十六进制数值;7. 字节值表:由若干个字节值组成,也可以是用
26、引号括起来的字符串;8. 驱动器号:0驱动器A、1驱动器B、2驱动器C、3驱动器D等;9. 命令是单个字母,命令和参数的大小写可混合输入;10. 可用F1、F2、F3、Ins、Del、左移键、右移键等编辑键来编辑本行命令;11. 当命令出现语法错误时,将在出错位置显示“ Error”;12. 可用Ctrl+C或Ctrl+Break来终止当前命令的执行,还可用Ctrl+S来暂停屏幕显示(当连续不断地显示信息时)。下面对DEBUG命令作具体介绍:1. 内存显示命令D(Dump Command)D命令用来显示内存单元的值,包括下列两种格式:(1) D 显示由指定地址开始的若干内存单元的值。对于80列
27、显示模式,显示128个字节。如果未指定参数,则一个D命令的结束地址开始显示。若前面未用过D命令,则缺省从CS:IP开始显示。(2) D 该命令显示由指定的所有内存单元的值。执行D命令后,屏幕左边显示的是内存地址,中间是从该地址开始的若干字节值(十六进制),右边是每个字节对应得ASCII字符,其中,“.”表示不可打印字符。若只给出偏移地址,则使用DS当前值作为段地址。例如: D 2000:100 ;显示从2000:0100H开始的内存单元的值 D 100 ;显示从DS:100H开始的内存单元的值 D CS:100 ;显示从CS:100H开始的内存单元的值D ;显示从CS:IP开始的内存单元的值2
28、. 内存修改命令E(Enter Command)E命令用来设置指定内存单元的值,包括下列两种格式:(1) E;(2) E。 若只给出偏移地址,则使用DS当前值作为段地址。 第一种格式以交互方式逐个修改连续的内存单元。键入该命令后,DEBUG显示指定地址及相应内存单元的值,等待用户修改。此时,可以采取下列操作: 输入一个新的值; 键入空格跳到下一个地址单元; 键入“-”返回上一个地址单元; 按回车键结束E命令。第二种格式用来修改从指定地址开始的内存区域。DEBUG将这些值依次写入始于指定地址的连续内存单元。其中,是以空格或逗号分隔的若干十六进制字节或字符串。例如:E 01 123 0A ;将内存
29、单元DS:0DS:4的值设置为01H、31H、32H、33H、0AH注意,E命令后必须指定内存地址。3. 寄存器命令R(Register Command) R命令用来显示和修改寄存器的值,包括下列两种格式。(1) R显示所有寄存器和8个标志位的值,并反汇编CS:IP所指 的命令。(2) R 显示指定寄存器的值,并等待用户键入新的值,按回车键结束R的命令。其中,只能是8086的16位寄存器AX、BX、CX、DX、SP、BP、SI、DI、DS、ES、SS、CS、IP、与F(标志寄存器)。其中,显示的8个标志位的符号对应符号如下表所示。标志名称溢出OF方向DF中断IF负号SF零ZF辅助进位AF奇偶PF进位CF置位状态OVDNEINGZRACPECY复位状态NVUPDIPLNZNAPONC如果想修改标志寄存器的内容,可以输入如下命令。-R F屏幕将显示8个标志位的值,然后等待用户修改。只要输入这些符号就可以设置对应标志位的值,键入符号的个数与顺序可以任意。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1