X86 汇编语言程序设计
实验报告
姓名:
周芙蓉
学号:
71113108
东南大学计算机科学与工程学院、软件学院
School of Computer Science & Engineering
College of Software Engineering
Southeast University
二 0 15 年 5 月
实验一 汇编语言程序上机过程
一)实验目的
学会安装“16 位汇编程序开发软件”的安装,完成将汇编语言源程序录入进计算机、
利用 ml.exe 进行汇编,LINK 进行链接,并用 DEBUG 调试 16 位程序的全部过程。本实验
大家不必了解程序细节,只是为了熟悉开发环境和上机过程。
二)实验内容
1. 写 16 位汇编程序,从键盘输入一个字符串,然后换行后将该字符串输出到屏幕。
1)源程序
.8086
.MODEL SMALL
.DATA
CR DB 0AH,0DH,'$'
N EQU 20
STRING DB N DUP(?)
.CODE
START:
MOV AX,@DATA
MOV DS,AX
MOV DX,OFFSET STRING
MOV AH,0AH
INT 21H;输入一个字符串,STRING[0]中存储缓冲区最大字节数,STRING[1]中存储实际
字节数
MOV DX,OFFSET CR
MOV AH,09H
INT 21H;换行回车
MOV BL,STRING[1]
MOV BH,0;
MOV BYTE PTR STRING[BX]+2,'$'
MOV DX,OFFSET STRING+2;STRING[0]和 STRING[1]分别存储的是缓冲区最大字节数和
实际字节数
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
END START
2)运行结果贴图
3)编程与调试心得(遇到的问题和解决的办法,以及获得的收获)
1.第一次写好程序只看到 Z:>rem success!无法得到想要的结果,就暂时将程序搁置到一
边,十几天过后再重新看自己的程序时对代码的作用影响已不深刻,所以在今后的汇编中要
有必要的注释。
2.查过 dos 功能调用表才知道 MOV AH,0AH;INT 21H;将输入的内容储存在数组 STRING
中,同时 STRING[0]中存放的是最大字节数,STRING[1]中存放的是实际字节数。这就是 MOV
BYTE PTR STRING[BX]+2,'$';这一步将 STRING[BX]+2 的原因,将’$’放入输入字符的末
尾以提示输入过程的完成,否则回车也会存入 STRING 数组。
实验二 顺序程序设计
一)实验目的
通过这一部分的实验,进一步熟悉汇编过程和 DEBUG 调试过程;掌握用汇编语言编写
顺序程序。
二)实验内容
1. 写完整程序 16 位程序,在内存中从 Table 开始的 10 个单元中连续存放 0 到 9 的平方
值,任给一个 0 到 9 的数 X,该数存放在内存单元 XX 中,用 XLAT 指令查表求 X 的平方
值,并将结果存于内存 YY 单元中。编写程序,并在 DEBUG 中进行调试和验证结果。
1)源程序
.8086
.MODEL SMALL
.DATA
TABLE DB 0,1,4,9,16,25,36,49,64,81
XX DB 4
YY DB ?
.CODE
START:
MOV AX,@DATA
MOV DS,AX
MOV BX,OFFSET TABLE
MOV AL,XX
XLAT
MOV YY,AL
MOV AH,4CH
INT 21H
END START
2)运行结果贴图
3)编程与调试心得(遇到的问题和解决的办法,以及获得的收获)
1.要掌握 xlat 的原理。其操作为[BX]+[AL]---->AL 将 BX 为首地址的,偏移地址为 AL 的内容
送给 AL。
实验三 循环程序设计
一)实验目的
通过实验,可以掌握循环结构的各种实现方法,进一步了解循环结构中初始化部分、循
环体部分、循环控制部分的功能以及他们彼此之间的关系。尤其是多重循环中外层循环和内
层循环之间的关系。
二)实验内容
1. 所 谓 回 文 字 符 串 是 指 一 个 字 符 串 正 读 和 倒 读 都 是 一 样 的 , 例 如 字 符 串
‘ABCDEFFEDCBA’就是一个回文字符串,而字符串‘ABCFDDCAB’就不是回文字符串。
现在编写完整的 16 位汇编程序,输入一个字符串,判断该字符串是否为回文字符串,并用
“It is a palindrome”或“It is NOT a palindrome”作为输出。
1)源程序
.8086
.MODEL SMALL
.DATA
MSG1 BYTE 'It is a palindrome','$'
MSG2 BYTE 'It is NOT a palindrome','$'
CR DB 0AH,0DH,'$'
STRING DB 20 DUP(?)
.CODE
START:
MOV AX,@DATA
MOV DS,AX
MOV DX,OFFSET STRING
MOV AH,0AH
INT 21H;输入一个字符串,STRING[0]中存储缓冲区最大字节数,STRING[1]中存储实际
字节数
MOV DX,OFFSET CR
MOV AH,09H
INT 21H;换行回车
LEA SI,STRING+2;将输入字节的首个有效地址赋给 si
MOV BL,STRING[1]
MOV BH,0;将实际长度存储于 bx
MOV CX,BX
ADD BX,SI
MOV DI,BX;
DEC SI
AGAIN:INC SI
DEC DI
MOV AL,[SI]
CMP AL,[DI]
LOOPZ AGAIN
JZ P1
MOV DX,OFFSET MSG2
MOV AH,09H
INT 21H
JMP DONE
P1:MOV DX,OFFSET MSG1
MOV AH,09H
INT 21H
DONE: MOV AH,4CH
INT 21H
END START
2)运行结果贴图
3)编程与调试心得(遇到的问题和解决的办法,以及获得的收获)
1.要 明 确 区 分 何 时 使 用 的 是 有 效 地 址 何 时 使 用 的 是 有 效 地 址 中 的 内 容 。 例 如 LEA
SI,STRING+2;就是将 string+2 的有效地址赋给 si。 MOV BL,STRING[1];MOV BH,0;将
string[1]中的值即实际长度存储于 bx。 MOV AL,[SI];CMP AL,[DI]比较的也是 si,di 地
址对应下的内容。
2. 请编写 16 位完整汇编程序,在一个升序字节数组 BUFF 中查找数 N,找到后将此数从数
组中删除,并使得 CF=0;没找到返回 CF=1。
1)源程序(删除 3)
.8086
.MODEL SMALL
.STACK 100H
.DATA
ARRAY DB 0,1,2,3,4,5,6,7,8,9
LENG EQU $-ARRAY
A_END DW ?
A_HEAD DW ?
N DB 3
.CODE
START:
MOV AX,@DATA
MOV DS,AX
MOV AL,LENG
MOV AH,0
LEA BX,ARRAY
MOV A_HEAD,BX;初始化 head
ADD AX,BX
MOV DI,AX
DEC DI
MOV A_END,DI;初始化 end,end=head+leng-1
P1:MOV DL,0
MOV DL,[BX]
CMP DL,N;源操作数是常数
JNE P2;不相等则跳转 p2
JMP DELETE;相等则跳转至 delete 进行删除操作
p2:INC BX
CMP BX,A_END
JBE P1;BX<=END 则继续寻找 N
STC;CF 置 1
JMP DONE
DELETE:MOV DI,A_END
SUB DI,BX
MOV CX,DI;计算出数组中 n 后面剩余的长度
MOVE:MOV DX,[BX+1]
MOV [BX],DX
INC BX
LOOP MOVE
DEC A_END;将数组最后的地址前移一位
CLC;清除 cf 位
JMP DONE
;调整数组并重新打印
DONE:MOV CX,0
MOV CX,A_END
LEA AX,ARRAY
SUB CX,AX
INC CX
MOV BX,0
PRINT:MOV DL,[ARRAY+BX]
;将 DL 中的数字转换成 ASCII 码输出在屏幕上
ADD DL,30H
MOV AH,02H
INT 21H
INC BX
LOOP PRINT
MOV AH,4CH
INT 21H
END START
2)运行结果贴图