实验1:掌握汇编语言程序的上机步骤
一、实验目的
1. 掌握汇编语言程序的上机步骤
- (1) 用编辑程序 (如EDIT、记事本等) 编辑汇编语言源程序 (建立.ASM文件)
- (2) 用MASM程序产生OBJ文件
- (3) 用LINK程序产生EXE文件
- (4) 程序的运行 (用DEBUG或在DOS下直接运行)
- 2. 掌握DEBUG的使用方法
- (3) 用LINK程序产生EXE文件
- (2) 用MASM程序产生OBJ文件
二、实验内容
- 在数据段DATA中有两个字数据X和Y, 假设X=1122H, Y=3344H, 编程求两个字的和,结果存放到Z单元中。
- 从SOURCE_BUFFER单元开始存放了20个字母A, 编程将这20个字母A的字符串传送到DEST_BUFFER开始的单元中。
- 从SOURCE_BUFFER单元开始存放了20个字母A, 编程将这20个字母A的字符串向下移10个单元。
三、设计思想
3.1 实验内容一
先在数据段中定义三个字类型变量X、Y和Z,将X赋值为1122H,Y赋值为3344H,Z不做初始化。然后将数据段的段地址写入DS寄存器,其他段地址使用默认值。
在代码段中先通过MOV指令将X移至AX寄存器,再通过ADD指令将AX的内容与Y进行相加并保存至AX,最后将AX的内容通过MOV指令赋值给Z,完成实验。
具体流程图见下图1所示:
图1 实验内容一流程框图
3.2 实验内容二
先在数据段内开辟20个空间放置字符A,其首地址为SOURCE_BUFFER;开辟20个空间并不初始化,其首地址为DEST_BUFFER。然后将数据段的段地址写入DS寄存器,其他段地址使用默认值。
为实现串传送,可使用LOOP指令和MOV指令的寄存器相对寻址将SOURCE_BUFFER中的值逐个写入DEST_BUFFER中。先将20赋值给CX寄存器(设定赋值操作循环次数为20次),将0赋值给SI(记录当前赋值到的字符位置),再设置赋值循环:将SOURCE_BUFFER后第SI个空间的地址赋值给DEST_BUFFER后第SI个空间,SI逐次递增。
具体流程图见下图2所示:
图2 实验内容二流程框图
3.3 实验内容三
内容三思路与内容二类似,但需注意在传送时按照从后往前顺序进行,防止前面的数据覆盖后面的数据,造成数据丢失。并且,我们也不需要再定义DEST_BUFFER额外的空间进行数据存放,但需要使用两个寄存器SI和DI,将它们分别初始化为19和29。其中,SI表示源地址相对于SOURCE_BUFFER首地址的偏移量,DI表示目的地址相对于SOURCE_BUFFER首地址的偏移量。
据此,我们首先在数据段内开辟20个空间放置字符A,10个空白空间,它们的首地址为SOURCE_BUFFER。然后将数据段的段地址写入DS段寄存器和ES段寄存器。
其后,将20赋值给CX寄存器(设定赋值操作循环次数为20次),将19赋值给SI寄存器,将29赋值给DI寄存器,再设置赋值循环:将SOURCE_BUFFER后第SI个空间的地址赋值给SOURCE_BUFFER后第DI个空间,SI、DI逐次递减。
为了方便观察结果,我们利用LOOP和MOV指令将源地址后的10个空间数据进行归零处理。
具体流程图见下图3所示:
图3 实验内容三流程框图
四、程序代码
4.1 实验内容一
DATA SEGMENT
;定义变量
X DW 1122H
Y DW 3344H
Z DW ?
DATA ENDS
STACK SEGMENT STACK
DB 200 DUP(?)
STACK ENDS
CODE SEGMENT
;定义堆栈大小(例如,200字节)
ASSUME DS:DATA,CS:CODE,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,X
ADD AX,Y
MOV Z,AX
MOV AH,4CH
INT 21H
CODE ENDS
END START
4.2 实验内容二
DATA SEGMENT
;定义变量
SOURCE_BUFFER DB 20 DUP('A')
DEST_BUFFER DB 20 DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV CX,20
MOV SI,0
NEXT:
MOV AL,SOURCE_BUFFER[SI]
MOV DEST_BUFFER[SI],AL
INC SI
LOOP next
;程序结束,返回DOS
MOV AH,4CH
INT 21H
CODE ENDS
END START
4.3 实验内容三
DATA SEGMENT
;定义变量
SOURCE_BUFFER DB 20 DUP('A'),10 dup(0)
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,ES:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV CX,20
MOV SI,19
MOV DI,29
NEXT:
MOV AL,SOURCE_BUFFER[SI]
MOV SOURCE_BUFFER[DI],AL
DEC SI
DEC DI
LOOP NEXT
MOV CX,10
MOV SI,0
NAXT2:
MOV SOURCE_BUFFER[SI],0
INC SI
LOOP NAXT2
;程序结束,返回DOS
MOV AH,4CH
INT 21H
CODE ENDS
END START
五、结果分析
5.1 输出结果及分析
(1)实验内容一
图4 实验内容一开始
图5 实验内容一结果
实验开始时在DS数据段内有1122H和3344H,相加之后结果为4466H。
(2)实验内容二
图6 实验内容二开始
图7 实验内容二结果
实验开始时DS数据段内有20个A,运行结果为DS数据段内有40个A,说明成功将SOURCE_BUFFER单元存放的20个字母A传送到DEST_BUFFER中。
(3)实验内容三
图 8 实验内容三开始
图 9 实验内容三结果
实验开始时DS数据段内有20个A,运行结果为DS数据段内20个A后移10个空间。
5.2 对程序调试的总结及分析
调试程序需要我们将编写的.asm文件编译为目标文件(.obj)、列表文件(.lst)和交叉引用文件(e.crf),再将目标文件编译为可执行文件(.exe),最好通过debug直观观察各个标志位或者寄存器的情况。
在刚开始调试程序时,由于没有事先将需调试的程序放置在同目录文件夹下,导致按照步骤操作时,一直显示没有找到相关文件。后来,在课程上看了老师的操作步骤后发现自己的错误并及时改正,学会了基本的调试步骤。
后来,在实验内容二将.asm文件编译为.obj文件时,由于将英文格式的“,”打成了中文格式的“,”,导致无法编译。后来根据错误提示语,成功解决问题。
5.3 对程序设计的总结及分析
汇编语言不同于我们以前学过的其他高级语言如C、C++、java等一样符合人的自然语言描述,它需要我们在进行编写前,事先设计详细的流程图,明确自己需要用到的指令集和寄存器,而后根据流程图,编写出符合实验要求的汇编程序。
在程序编译成功后,利用debug中的-t、-u、-g等指令详细观察不同时刻下的寄存器及标志位的变化,对它们前后数据进行对比,判断程序功能是否正确。并且,通过一步步地调试,直观了解每一步操作实现的效果,使我更加熟悉汇编程序。
5.4 心得与体会
本次为第一次汇编语言上机实验。通过这次实验,我掌握了汇编语言的上机步骤以及基本的debug的用法,为之后进行汇编语言编程打下了良好的基础。同时,对于理论课上抽象模糊的理论知识,有了直观地认识和了解。
实验课上老师对编译过程和每一个实验内容的代码进行了详细的讲解,这使我能够根据步骤,一步步地轻松完成实验。
并且,通过查阅相关资料,我知道了assume伪指令通过将逻辑段的段名和对应的段寄存器关联起来,向汇编程序说明所定义的逻辑段属于何种类型的逻辑段(CS寄存器系统已经自动给定);明白了CPU在执行LOOP指令时,首先会先将CX寄存器中的值减一,然后判断CX的值是否为零,不为零的话则跳转到标号处进行执行,否则继续向下执行。
据此,我进一步认识、理解了汇编语言。对于寄存器中分配地址、各种寻址方式、数据保存等,我有了新的认识,能够将理论课上的知识转移到实践中去。