汇编语言简明教程 实验报告
提示:本文是应燕山大学实验要求,经抓耳挠腮大量掉发查阅资料后所得
文章目录
前言
提示:以下是本篇文章正文内容,实验一、二是在DOSBOX窗口中直接编写指令,实验三、四、五是在MASMPlus中编写的。
实验一 汇编语言源程序的输入
1.1实验内容
本实验要求在DEBUG状态下输入汇编源程序,并用DEBUG命令进行调试。用单步跟踪的方法验证指令的功能。
1.2实验过程
-a开始输入指令
-t按步执行指令,查看执行完一条指令,屏幕显示所有寄存器内容和下一条指令地址和指令
查找对应寄存器或内存地址的数据
直接连续输入指令之后,-t查找就可
1.3实验结果
实验二 数 据 的 建 立 与 传 送 程 序
2.1实验内容
在DEBUG状态下,分别输入下面各程序段,每输入完一个程序段,用G命令进行连续方式执行程序,在连续执行时,要记录程序的执行结果。将一段从小到大又从大到小的数据存储,又传递给其他的数据段。
2.2实验过程
1.第一段程序指令:令cx等于数据块的个数31,是根据数据地址循环递增进行传递数据;
2.第二段程序指令:MOVSB字符串传送指令,指令按字节进行传送地址,通过SI和DI两个寄存器控制字符串的源地址和目的地址,将DS:SI这段地址中字节复制到ES:DI指向的地址。
3.第三第四段程序指令:在使用REP MOVSB指令中,将位于DS段的由SI所指向的存储单元的字节或字传送给位于ES段的由DI所指出的存储单元,修改SI和DI,从而指向下一个元素,其中CLD和STD都是用于串操作指令中操作方向标志位DF,CLD设置DF复位,即DF=0,STD设置DF置位,即DF=1。
4.注意跳转指令。
5.-g命令完成指令执行结束指令时,需要-g=XXXX XXXX,前一个地址是运行的程序开始的地址,后一个地址是程序运行结束的地址,否则,会遇到程序运行卡住的问题。
2.3实验结果
1.在内存10000H单元开始,建立00H~0FH~00H 31个数,要求00H~0FH数据逐渐增大,0FH~00H逐渐减小。该程序从内存CS:0100H地址开始输入。
代码如下(示例):
MOV AX, 1000H
MOV DS, AX
MOV SI, 0
MOV CL, 0FH
XOR AX, AX
PPE1: MOV [SI], AL
INC SI
INC AL
DEC CL
JNZ PPE1
MOV CX, 10H
PPE2: MOV [SI], AL
INC SI
DEC AL
LOOP PPE2
INT 20H
结果(示例):
2.把上一个程序的执行结果(建立的31个字节数据块,其首地址在10000H),分几种方式传送到以下指定的区域。
(a)检查内存数据块的传送情况,可用“D”命令。
代码如下(示例):
MOV AX, 1000H
MOV DS, AX
MOV SI, 0
MOV DI, 5050H
MOV CX, 1FH ; 数据块长度是31
PPEA: MOV AL, [SI]
MOV [DI], AL
INC SI
INC DI
LOOP PPEA
INT 20H
内存数据块如下(示例):
(b)用串传送指令MOVSB,把数据块传送到15150H开始的区域,该程序从内存CS:0200H开始输入。
代码如下(示例):
检查程序最后的执行结果,可用“D”命令,例如:
-D1000:5150↙
内存数据块如下(示例):
©用重复串操作指令“REP MOVSB”把数据块传送到15250H开始的区域。该程序从CS:250H地址开始输入。
指令代码如下(示例):
检查程序的最后执行结果时,可用:
-D1000: 5250↙
内存数据块如下(示例):
(d)用串操作的减量工作方式,把数据块传送到25050H开始的区域。该程序从CS:0300H开始输入。
指令代码如下(示例):
检查程序的最后执行结果,用D命令:
-D2000:5050↙
内存数据块如下(示例):
实验3 分 支 程 序 设 计
3.1实验内容
3.1.1给出三个有符号数,编写一个比较相等关系的程序
(1)如果这三个数都不相等,则显示0;
(2)如果这三个数中有两个数相等,则显示1;
(3)如果这三个数都相等,则显示2;
3.1.2找出字符串的大写字母和小写字母
从键盘上输入一串字符到输入缓冲区,找出其中的大写字母和小写字母,并分别统计它们的个数,结果放到变量num1和num2中,要求在屏幕输出显示所有字母及变量num1和num2的值。
3.2实验过程
CMP比效指令
INC加一指令
DEC减一指令
JNB 大于等于
JNBE 大于
LOOP 循环控制指令
在输出字符串的时候,需要有“$”才可以停止输出字符串
输入有符号的字符串以及直接输出十进制数字时,引入含有调用输入输出子程序的声明语句和宏定义的文件io.inc。
3.3实验结果
3.3.1
指令代码如下(示例):
include io.inc
.model small
.stack
.data
msg1 db 10,13,'Please input var1:$'
msg12 db 10,13,'Please input var2:$'
msg13 db 10,13,'Please input var3:$'
msg2 db 10,13,'Please ouput:$'
msg3 db 10,13,'$'
var1 db ?
var2 db ?
var3 db ?
.code
.startup
mov dx,offset msg1;提示输入字符串
mov ah,9
int 21h
call readsib;输入第一个字符
mov var1,al
mov bl,var1
mov dx,offset msg12;提示输入字符串
mov ah,9
int 21h
call readsib;输入第二个字符
mov var2,al
mov cl,var2
mov dx,offset msg13;提示输入字符串
mov ah,9
int 21h
call readsib;输入第三个字符
mov var3,al
mov al,var3
mov dx,offset msg2;输出结果
mov ah,9
int 21h
mov dl,0;记录最终结果
cmp bl,cl
jne one;若不相等跳转
inc dl;若相等加一
one:cmp al,cl
jne two
inc dl
two:cmp bl,al
jne three
inc dl
three:cmp dl,3h
jne last
dec dl
last:add dl,30h
mov ah,02h
int 21h
end
```bash
指令代码检测结果如下(示例):
3.3.2
指令代码如下(示例):
include io.inc
.model small
.stack
.data
buffer db 60;字符串所占的字节数
db ?;输入字符串字符个数,自动填充
db 60 dup(0);数组存储输入字符串
msg1 db 10,13,'Please input:$'
msg2 db 10,13,'varL:$'
msg3 db 10,13,'varS:$'
msg4 db 10,13,'$'
msg5 db 10,13,'Please ouput:$'
varL db 0;大写字母个数
varS db 0;小写字母个数
.code
.startup
mov dx,offset msg1;提示输入字符
mov ah,9
int 21h
lea dx,buffer;输入字符串
mov ah,0ah
int 21h
mov bl,buffer+1;若为空
cmp bl,0
jz exit
lea si,buffer+2;两个字节代表一个字
mov cl,bl
again:
mov al,BYTE ptr[si]
cmp al,'z'
jnbe next;比z大,跳过
cmp al,'a';比z小
jnb number2;大于等于a,小写字母数字增加
cmp al,'Z';比a小
jnbe next;比Z大,跳过
cmp al,'A';比Z小
jnb number1;大于等于A
jmp next;比A小,跳过
number1:inc varL
jmp next
number2:inc varS
jmp next
next:inc si
loop again
mov bh,0
add bx,dx
mov BYTE ptr[bx+2],'$'
mov buffer,13
mov buffer+1,10
exit:
mov ah,9
int 21h
mov dx,offset msg2;大写字母个数
mov ah,9
int 21h
mov al,varL
call dispsib
mov dx,offset msg3;小写字母个数
mov ah,9
int 21h
mov al,varS
call dispsib
end
指令代码检测结果如下(示例):
实验4 分 支 程 序 设 计
4.1实验内容
设有 10 个学生的成绩分别为 56、69、84、82、73、88、99、63、100 和 80 分。试编制程序分别统计低于 60 分、60~69 分、70~79 分、80~89 分、90~99 分及 100 分的人数存放到 s5、s6、s7、s8、s9 及 s10 单元中。这一题目的算法很简单,成绩分等部分采用分支结构,统计所有成绩则用循环结构完成。
4.2实验过程
注意dw与db所占的字节不同,dw占据内存两个字节,db占据内存一个字节,在循环程序中,改变的量——所加的偏移地址是目标字符串的类型。编写将存放于 S5、S6、S7、S8、S9 及 S10 单元中的数据在屏幕上显示出来的部分程序。
4.3实验结果
指令代码如下(示例):
;PROGRAM TITLE GOES HERE――result
;************************************
DATAREA SEGMENT ;DEFINE DATA SEGMENT
GRADE DW 56,69,84,82,73,88,99,63,100,80
S5 DW 0
S6 DW 0
S7 DW 0
S8 DW 0
S9 DW 0
S10 DW 0
DATAREA ENDS
;************************************
PROGNAM SEGMENT ;DEFINE CODE SEGMENT
;----------------------------
MAIN PROC FAR ; MAIN PART OF PROGRAM
ASSUME CS:PROGNAM, DS:DATAREA
START: ; STARTING EXECUTION ADDRESS
; SET UP STACK FOR RETURN
PUSH DS ; SAVE OLD DATA SEGMENT
SUB AX,AX ; PUT ZERO IN AX
PUSH AX ; SAVE IT ON STACK
; SET DS REGISTER TO CURRENT DATA SEGMENT
MOV AX,DATAREA ; DATAREA SEGMENT ADDR
MOV DS,AX ; INTO DS REGISTER
; MAIN PART OF PROGRAM GOES HERE
MOV S5, 0 ; INITIALIZE COUNTER
MOV S6, 0
MOV S7, 0
MOV S8, 0
MOV S9, 0
MOV S10, 0
MOV CX, 10 ; INITIALIZE LOOP COUNT VALUE
MOV BX, OFFSET GRADE ; INITIALIZE FIRST ADDR12
COMPARE:
MOV AX,[BX] ; GET A RESULT
CMP AX, 60 ; <60?
JL FIVE
CMP AX, 70 ; <70?
JL SIX
CMP AX, 80 ; <80?
JL SEVEN
CMP AX, 90 ; <90?
JL EIGHT
CMP AX, 100 ; =100?
JNE NINE
INC S10
JMP SHORT CHANGE_ADDR
NINE: INC S9
JMP SHORT CHANGE_ADDR
EIGHT: INC S8
JMP SHORT CHANGE_ADDR
SEVEN: INC S7
JMP SHORT CHANGE_ADDR
SIX: INC S6
JMP SHORT CHANGE_ADDR
FIVE: INC S5
CHANGE_ADDR:
ADD BX, 2
LOOP COMPARE
MOV CX,6;设置6个成绩阶段
MOV SI,OFFSET S5;从S5开始输出
AGAIN:MOV DX,[SI];
ADD DX,30H;将数字转化为字符
MOV AH,02;调用02号ah输出字符
INT 21H;
MOV DL,20H;在屏幕上显示空格(20h)
MOV AH,02;调用02号ah输出字符
INT 21H
ADD SI,2;一个Sx是dw类型,占据两个字节
LOOP AGAIN;
RET ; RETURN TO DOS
MAIN ENDP ; END OF MAIN PART OF PROGRAM
; ------------------------------
PROGNAM ENDS
;***************************
END START ; END ASSEMBLY
指令执行结果如下(示例):
实验5 学 生 成 绩 名 次 表 实 验
5.1实验内容
将 0~100 之间的 10 个成绩存入首址为 1000H 的单元中。1000H+i 表示学号为 i 的学生成绩,编写程序能在 2000H 开始的区域排出名次表。2000H+i 为学号 i 的学生的名次。
5.2实验过程
调用子程序,将十六进制转化为十进制,对数值进行除10求余压栈,最后再逐一出栈进行显示,需要注意的是入口参数是ax,而数值是al,需要将al进行符号数扩展后,再调用子程序。
5.3实验结果
指令代码如下(示例):
include io.inc
CRLF MACRO
MOV DL, 0DH
MOV AH, 02H;回车
INT 21H
MOV DL, 0AH
MOV AH, 02H;换行
INT 21H
ENDM
DATA SEGMENT
STUNUM EQU 10
MESS DB 'INPUT 10 STUDENTS SCORE: ',0DH,0AH,'$';提示输入10位同学的成绩
ERROR DB 'INPUT ERROR!',0DH,0AH,'$';提示输入错误
ORG 1000H
SCORE DB 10 DUP (?);成绩
ORG 2000H
SEQU DB 10 DUP (?)
DATA ENDS
STACK SEGMENT
STA DW 12 DUP (?)
TOP DW ?
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START: MOV AX, DATA
MOV DS, AX
MOV ES, AX
MOV SP, TOP ; 初始化
MOV DX, OFFSET MESS
MOV AH, 09H
INT 21H ; 显示提示输入信息
MOV SI, OFFSET SCORE ; 成绩表首址
MOV CX, STUNUM ; 学生数送CX
UUU: CALL GETNUM ; 读取键入数值送DX
MOV [SI], DL ; 存入成绩表缓冲区
INC SI ; 指向下一单元
LOOP UUU
MOV CX, STUNUM ; 学生数
MOV DI, OFFSET SEQU ; 名次表首址
VVV: CALL SCAN ; 扫描子程序
MOV AL, STUNUM ; 学生数
SUB AL, CL
INC AL ; 计算名次
MOV BX, DX
MOV [DI+BX], AL ; 记DX学号对应名次
LOOP VVV
MOV CX, STUNUM ; 学生数
MOV SI, OFFSET SEQU ; 名次表首址
WWW: MOV AL, [SI]
CALL DISP1
CRLF
INC SI
LOOP WWW ; 显示排定的学生名次
MOV AX, 4C00H
INT 21H
SCAN PROC NEAR ; 子程序,每扫描一遍成绩表缓冲区, 找出其中成绩最高者由DX指针指示对应学生 之后将该成绩清除,以便下一次扫描
PUSH CX
MOV CX, STUNUM ;学生数
MOV AL, 00H ;最低成绩
MOV BX, OFFSET SCORE
MOV SI, BX ;指向成绩表首址
CCC:
CMP AL, [SI]
JAE JJJ;AL中的成绩不低于成绩表指针SI所指单元的成绩则转JJJ
MOV AL, [SI] ;AL存放较高的成绩
MOV DX, SI
SUB DX, BX ;DX为对应学号
JJJ:INC SI ;指向下一单元
LOOP CCC
ADD BX, DX
MOV BYTE PTR[BX], 00H ;本次扫描成绩最高者清0
POP CX
RET
SCAN ENDP
DISP1 PROC NEAR
PUSH CX
MOV BL, AL
MOV DL, BL
MOV CL, 04
ROL DL, CL
AND DL, 0FH
CALL DISPL
MOV DL, BL
AND DL, 0FH
CALL DISPL
POP CX
RET
DISP1 ENDP
DISPL PROC NEAR
JMP DDD2;将程序跳转到DDD2
DDD2:
MOV AL,DL;将dl中的值传递给al
CBW;子程序传递参数是ax,将al字符扩展到ax
CALL EXCHANGE;调用子程序将16进制转化为10进制
RET
EXCHANGE PROC;
PUSH AX
PUSH BX
PUSH CX
PUSH DX
XOR CX,CX
CMP AX,0
JNE L1;ax不为0
ADD AX,'0';ax为0时特殊处理
PUSH AX
MOV AX,0
MOV CX,1
L1:MOV BL,AL;
ADD BL,AH
CMP BL,0
JNE L2;除10取余数不为0
JMP L3
L2:
MOV DL,10
DIV DL;除10求余保存
MOV BX,0
MOV BL,AH
ADD BL,'0'
PUSH BX;位数加1
INC CX;商作为被除数继续循环
MOV AH,0
JMP L1
L3:
POP DX;为0跳出
MOV AH,2
INT 21H
LOOP L3
POP DX
POP CX
POP BX
POP AX
JMP EXIT
EXIT:RET
EXCHANGE ENDP
DISPL ENDP
GETNUM PROC NEAR
PUSH CX
XOR DX, DX
GGG: MOV AH, 01H
INT 21H
CMP AL, 0DH
JZ PPP
CMP AL, 20H
JZ PPP
SUB AL, 30H
JB KKK
CMP AL, 0AH
JB GETS
CMP AL, 11H
JB KKK
SUB AL, 07H
CMP AL, 0FH
JBE GETS
CMP AL, 2AH
JB KKK
CMP AL, 2FH
JA KKK
SUB AL, 20H
GETS: MOV CL, 04
SHL DX, CL
XOR AH, AH
ADD DX, AX
JMP GGG
KKK: MOV AH, 09H
MOV DX, OFFSET ERROR
INT 21H
PPP: PUSH DX
CRLF
POP DX
POP CX
RET
GETNUM ENDP
CODE ENDS
END START
指令执行结果如下(示例):