实验二、寻找最大和最小数实验
一、
1、 2、 3、 4、
实验目的
学习循环程序结构,掌握编写循环处理程序的方法和技巧。 通过循环结构程序熟悉汇编语言程序设计的主要方法。 了解和掌握程序设计过程中算法的选择。 掌握汇编语言调试方法。
二、 实验内容
以buff 开始的内存单元中有9个有符号数(字节型DB ): 手动输入9个数字 请编写程序,找出最大的数并存入MAX 单元中,同时也找出最小的数并存入MIN 单元中,在Debug 下运行程序,查看数据区MAX 和MIN 的内容检验运行结果。
三、 编程过程
1、 在数据段设置buff 区(DB )存放10个被测试的数,再分别设置字节数据MAX 、MIN 。
BUF db MAX db MIN db
2、通过一个循环程序完成比较,先用第一个数与第二个,把较小的数放在AL 中,较大的数放在AH 中。
3、以后每次都用AL 与后面的数比较,把小的总放在AL 中;然后再用AH 与后面的数比较,把大的放在AH 中;比较结束后AL 和AH 分别放最小和最大数。
四、 实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以3.ASM 名保存。 2、 用MASM 文件汇编源程序,C>MASM 3;
3、 用LINK 连接程序,C>LINK 3; 形成3.EXE 文件。 4、 在DEBUG 调试环境下调试并运行3.EXE 程序。
5、 首先用R 指令,然后使用U 指令查看自己所编写的程序,确定断点后,使用G 命令
执行程序到断点,查看结果
程序执行输入9个数字:123456789 输出:最大值9,最小值1
6、程序运行结束后,用 D DS:0 检查数据区MAX 及MIN 内容,检查结果是否正确。
五、 思考
1、 查看DOS 操作系统把可执行程序装载到的内存的首地址及结束地址。 首地址:1447:0000 ,结束地址:1447:0053 2、 查看MAX 和MIN 的段地址及偏移地址。 MAX:1444:0024MIN :1444:0025
3、 分别计算数据段和代码段占用的地址空间大小。 数据段:40字节
代码段:54字节
附:源程序清单: DATA SEGMENT
STR DB 0AH,0DH,"please input number: ",'$'
BUF DB 10 ;BUF大小 DB ?
DB 10 DUP(?) ;字符个数 ;
CNT EQU $-BUF-3 ;循环次数 MAX DB ? ;存放最大数 MIN DB ? ;存放最小数 CRLF DB 0AH,0DH,'$' DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX
LEA DX,STR
MOV AH,09H INT 21H
INPUT: LEA DX,BUF MOV AH,0AH INT 21H
MOV CX,CNT-1
MOV BX,OFFSET BUF+2 ;首地址
MOV AH,[BX] ;假定第一个数为最大数 MOV AL,[BX] ; LOOP1: INC BX ; CMP AH,[BX] ; JGE NEXT1 ;AH MOV AH,[BX] ;AH JMP NEXT2
NEXT1: CMP AL,[BX] ; JNGE NEXT2
MOV AL,[BX] ;AL NEXT2: DEC CX
JNZ LOOP1 ; MOV MAX,AH ; MOV MIN,AL
MOV DL,CRLF MOV AH,02 INT 21H
MOV DL,MAX MOV AH,02 INT 21H
MOV DL,MIN MOV AH,02 INT 21H
MOV AH,4CH INT 21H CODE ENDS
END STAR
假定第一个数为最小数 指向下一个数 比较
中数大
中数小,替换 比较 中数大,替换 循环
存储最大数
实验三、统计学生成绩
一、
实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以t.ASM 名保存。
2、 用MASM 文件汇编源程序,C>MASM t; 如有错误,回到第一步,如没错误,到第三步.
3、 用LINK 连接程序,C>LINK t; 形成t.EXE 文件。
4、 在DEBUG 环境下运行调试程序:C> DEBUG t.EXE回车,使用U 命令反汇编自己编写的程序,查找到断点地址,用G 命令使程序执行到完成初始化的功能;
5、 此时使用D 命令查看数据段的内容,是否有学生的分数并查看s5、s6、s7、s8、s9、s10字节变量的地址及内容。
数据段有学生的分数,
S5 1444:0014 内容为0;S6 1444:0015 内容为0;S7 1444:0016 内容为0; S8 1444:0017 内容为0;S9 1444:0018 内容为0;S10 1444:0019 内容为0;
6、 然后查找程序功能结束的命令对应的断点地址,用G 命令使程序运行到断点; G 命令执行程序,程序结果如下: S5:5 S6:4 S7:3 S8:4 S9:3 S10:1
7、 此时再使用D 命令查看存储各分数段的学生人数是否正确。
各分数段的学生人数正确
实验四、查找字符
一、实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以5.ASM 名保存。 2、 用MASM 文件汇编源程序,C>MASM 5; 如有错误,回到第一步,如没错误,到第三步.
3、 用LINK 连接程序,C>LINK 5; 形成5.EXE 文件。 4、 运行程序:C> 5.EXE 回车 执行结果为:
在屏幕上先显示提示信息,例如please enter:后,等待键盘输入字符,输入字符
AABBCCDDEEFFGG ,输入结束后应在屏幕出现CHAR 字符出现的次数:
附实验三源程序: DATA SEGMENT SCORE DB 56,78,67,40,87,99,63,51,74,100,90,80,68,88,55,66,84,96,45,73
NUM_UNDER60 DB 0 NUM_60TO69 DB 0 NUM_70TO79 DB 0 NUM_80TO89 DB 0 NUM_90TO99 DB 0 NUM_100 DB 0 DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA MOV DS,AX XOR AX,AX MOV CX,20 LEA BX,SCORE
COMPARE:
CMP BYTE PTR [BX],60 JL UNDER60 JMP IS60TO69 IS60TO69:
CMP BYTE PTR [BX],70 JL _60TO69 JMP IS70TO79 IS70TO79:
CMP BYTE PTR [BX],80 JL _70TO79 JMP IS80TO89 IS80TO89:
CMP BYTE PTR [BX],90 JL _80TO89 JMP IS90TO99 IS90TO99:
CMP BYTE PTR [BX],100 JL _90TO99 JZ EQUAL100
UNDER60:
ADD NUM_UNDER60,1 JMP CON
_60TO69: ADD NUM_60TO69,1 JMP CON _70TO79: ADD NUM_70TO79,1 JMP CON _80TO89: ADD NUM_80TO89,1 JMP CON _90TO99: ADD NUM_90TO99,1 JMP CON EQUAL100: ADD NUM_100,1 CON: LEA BX,[BX+1] LOOP COMPARE LAST: MOV DL,NUM_UNDER60 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_60TO69 ADD DL,30H MOV AH,2 INT 21H MOV DL,' '
附实验四源程序: N Equ 50 ; 输入50个字符 Code0 Segment
Assume
SS:Code0,CS:Code0,DS:Code0
Main Proc Far
Start:
Mov AX,Code0
MOV AH,2 INT 21H MOV DL,NUM_70TO79 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_80TO89 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_90TO99 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_100 ADD DL,30H MOV AH,2 INT 21H MOV AH,4CH INT 21H CODE ENDS END START Mov SS,AX
Mov DS,AX
Jmp Begin
Char0 DB 0
intCount DB 0
Table DB N+1,?,N Dup(0)
strMessage DB 'Please input chars',10,13,36
Begin:
Lea DX,strMessage Mov AH,9
Int 21H ; 提示输入字符串
Lea DX,Table Mov AH,10
Int 21H ; 得到字符串
Push DX Call SubProc Exit0: Mov AH,4CH Int 21H Main EndP
SubProcProc Near Pop AX Pop BX Push AX
Inc BX ; 得到输入的实际字符串的长度的地址
Mov AX,BX ; 备份地址, 供判断用!
Add BL,[BX] ; 得到该字符串的最后一个字符的地址 Push BX ; 保存地址
Inc BX ; 地址预先加一 Sub0:
Dec BX ; 地址减一
Cmp BX,AX ; 是否地址已经超出范围?
Jz Sub4 ; 是
Cmp Byte Ptr [BX],0 ; 该地址是否有字符?
Jnz Sub1 ; 有
Jmp Sub0 Sub1:
Cmp Char0,0 ; 判断是否已有字符要记数?
Jnz Sub2 ; 有
MovCH,BytePtr [BX]
Mov Char0,CH ; 没有, 置初始字符. Sub3:
Mov Byte Ptr [BX],0 ; 清空该字符
IncintCount ; 加一 Jmp Sub0 Sub2:
MovCH,BytePtr [BX]
Cmp Char0,CH ; 判断该地址的字符是否要记数的字符?
Jnz Sub0 ; 不是
Jmp Sub3 Sub4:
Cmp Char0,BytePtr 0 Jz Ret0
Push
AX ; 保存ax Pop BX MovCL,intCount Mov CH,0
Push
CX ; 字符的个数
Call
HexToDec ; 转换 Mov AH,2 Mov DL,10 Int 21H Mov DL,13 Int 21H Mov DL,Char0
Int 21H ; 显示该字符 Mov DL,'='
Int 21H ; 显示“=”号
Call ShowNumber Mov Char0,0 Mov intCount,0
Pop AX ; 得到ax Pop
BX ; 得到地址 Dec BX Push BX
Cmp AX,BX ; 是否所有的字符已经判断完了? Jnz Sub5 Ret0:
Ret Sub5: Inc BX Jmp Sub0
SubProcEndP ;16进制转换成10进制 HexToDecProc Near Pop BX
Pop
AX ; 要转换的16进制数.
Push
BX ; 保存sp Xor BX,BX Hex0: Cmp AX,0AH
Jb Hex1 ; 已经比10小了,不用再减了!
Sub AX,0AH Add BX,10H Cmp BL,0A0H
Jb Hex0 Add BX,100H
Xor BL,BL
Mov CL,BH And CL,0FH Cmp CL,0AH Jb Hex0
Add BH,010H And BH,0F0H
Jmp Hex0 Hex1:
Add
BX,AX ; 转换到此结束! Pop AX Push
BX ; 保存结果. Push AX Ret HexToDecEndP
ShowNumberProc Near Pop AX Pop BX Push AX Mov DL,BH
And DL,0F0H Mov CL,4 Shr DL,CL
Or DL,30H
Mov AH,2
Int 21H ; 显示千位 Mov DL,BH
And DL,0FH Or DL,30H
Int 21H ; 显示百位 Mov DL,BL Mov CL,4 Shr DL,CL
Or DL,30H
Int 21H ; 显示十位 Mov DL,BL
And DL,0FH Or DL,30H
Int 21H ; 显示个位 Ret ShowNumberEndP Code0 EndS
End Start
实验二、寻找最大和最小数实验
一、
1、 2、 3、 4、
实验目的
学习循环程序结构,掌握编写循环处理程序的方法和技巧。 通过循环结构程序熟悉汇编语言程序设计的主要方法。 了解和掌握程序设计过程中算法的选择。 掌握汇编语言调试方法。
二、 实验内容
以buff 开始的内存单元中有9个有符号数(字节型DB ): 手动输入9个数字 请编写程序,找出最大的数并存入MAX 单元中,同时也找出最小的数并存入MIN 单元中,在Debug 下运行程序,查看数据区MAX 和MIN 的内容检验运行结果。
三、 编程过程
1、 在数据段设置buff 区(DB )存放10个被测试的数,再分别设置字节数据MAX 、MIN 。
BUF db MAX db MIN db
2、通过一个循环程序完成比较,先用第一个数与第二个,把较小的数放在AL 中,较大的数放在AH 中。
3、以后每次都用AL 与后面的数比较,把小的总放在AL 中;然后再用AH 与后面的数比较,把大的放在AH 中;比较结束后AL 和AH 分别放最小和最大数。
四、 实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以3.ASM 名保存。 2、 用MASM 文件汇编源程序,C>MASM 3;
3、 用LINK 连接程序,C>LINK 3; 形成3.EXE 文件。 4、 在DEBUG 调试环境下调试并运行3.EXE 程序。
5、 首先用R 指令,然后使用U 指令查看自己所编写的程序,确定断点后,使用G 命令
执行程序到断点,查看结果
程序执行输入9个数字:123456789 输出:最大值9,最小值1
6、程序运行结束后,用 D DS:0 检查数据区MAX 及MIN 内容,检查结果是否正确。
五、 思考
1、 查看DOS 操作系统把可执行程序装载到的内存的首地址及结束地址。 首地址:1447:0000 ,结束地址:1447:0053 2、 查看MAX 和MIN 的段地址及偏移地址。 MAX:1444:0024MIN :1444:0025
3、 分别计算数据段和代码段占用的地址空间大小。 数据段:40字节
代码段:54字节
附:源程序清单: DATA SEGMENT
STR DB 0AH,0DH,"please input number: ",'$'
BUF DB 10 ;BUF大小 DB ?
DB 10 DUP(?) ;字符个数 ;
CNT EQU $-BUF-3 ;循环次数 MAX DB ? ;存放最大数 MIN DB ? ;存放最小数 CRLF DB 0AH,0DH,'$' DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX
LEA DX,STR
MOV AH,09H INT 21H
INPUT: LEA DX,BUF MOV AH,0AH INT 21H
MOV CX,CNT-1
MOV BX,OFFSET BUF+2 ;首地址
MOV AH,[BX] ;假定第一个数为最大数 MOV AL,[BX] ; LOOP1: INC BX ; CMP AH,[BX] ; JGE NEXT1 ;AH MOV AH,[BX] ;AH JMP NEXT2
NEXT1: CMP AL,[BX] ; JNGE NEXT2
MOV AL,[BX] ;AL NEXT2: DEC CX
JNZ LOOP1 ; MOV MAX,AH ; MOV MIN,AL
MOV DL,CRLF MOV AH,02 INT 21H
MOV DL,MAX MOV AH,02 INT 21H
MOV DL,MIN MOV AH,02 INT 21H
MOV AH,4CH INT 21H CODE ENDS
END STAR
假定第一个数为最小数 指向下一个数 比较
中数大
中数小,替换 比较 中数大,替换 循环
存储最大数
实验三、统计学生成绩
一、
实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以t.ASM 名保存。
2、 用MASM 文件汇编源程序,C>MASM t; 如有错误,回到第一步,如没错误,到第三步.
3、 用LINK 连接程序,C>LINK t; 形成t.EXE 文件。
4、 在DEBUG 环境下运行调试程序:C> DEBUG t.EXE回车,使用U 命令反汇编自己编写的程序,查找到断点地址,用G 命令使程序执行到完成初始化的功能;
5、 此时使用D 命令查看数据段的内容,是否有学生的分数并查看s5、s6、s7、s8、s9、s10字节变量的地址及内容。
数据段有学生的分数,
S5 1444:0014 内容为0;S6 1444:0015 内容为0;S7 1444:0016 内容为0; S8 1444:0017 内容为0;S9 1444:0018 内容为0;S10 1444:0019 内容为0;
6、 然后查找程序功能结束的命令对应的断点地址,用G 命令使程序运行到断点; G 命令执行程序,程序结果如下: S5:5 S6:4 S7:3 S8:4 S9:3 S10:1
7、 此时再使用D 命令查看存储各分数段的学生人数是否正确。
各分数段的学生人数正确
实验四、查找字符
一、实验步骤
1、 在EDIT 或其它编辑方式下输入源程序,并以5.ASM 名保存。 2、 用MASM 文件汇编源程序,C>MASM 5; 如有错误,回到第一步,如没错误,到第三步.
3、 用LINK 连接程序,C>LINK 5; 形成5.EXE 文件。 4、 运行程序:C> 5.EXE 回车 执行结果为:
在屏幕上先显示提示信息,例如please enter:后,等待键盘输入字符,输入字符
AABBCCDDEEFFGG ,输入结束后应在屏幕出现CHAR 字符出现的次数:
附实验三源程序: DATA SEGMENT SCORE DB 56,78,67,40,87,99,63,51,74,100,90,80,68,88,55,66,84,96,45,73
NUM_UNDER60 DB 0 NUM_60TO69 DB 0 NUM_70TO79 DB 0 NUM_80TO89 DB 0 NUM_90TO99 DB 0 NUM_100 DB 0 DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA MOV DS,AX XOR AX,AX MOV CX,20 LEA BX,SCORE
COMPARE:
CMP BYTE PTR [BX],60 JL UNDER60 JMP IS60TO69 IS60TO69:
CMP BYTE PTR [BX],70 JL _60TO69 JMP IS70TO79 IS70TO79:
CMP BYTE PTR [BX],80 JL _70TO79 JMP IS80TO89 IS80TO89:
CMP BYTE PTR [BX],90 JL _80TO89 JMP IS90TO99 IS90TO99:
CMP BYTE PTR [BX],100 JL _90TO99 JZ EQUAL100
UNDER60:
ADD NUM_UNDER60,1 JMP CON
_60TO69: ADD NUM_60TO69,1 JMP CON _70TO79: ADD NUM_70TO79,1 JMP CON _80TO89: ADD NUM_80TO89,1 JMP CON _90TO99: ADD NUM_90TO99,1 JMP CON EQUAL100: ADD NUM_100,1 CON: LEA BX,[BX+1] LOOP COMPARE LAST: MOV DL,NUM_UNDER60 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_60TO69 ADD DL,30H MOV AH,2 INT 21H MOV DL,' '
附实验四源程序: N Equ 50 ; 输入50个字符 Code0 Segment
Assume
SS:Code0,CS:Code0,DS:Code0
Main Proc Far
Start:
Mov AX,Code0
MOV AH,2 INT 21H MOV DL,NUM_70TO79 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_80TO89 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_90TO99 ADD DL,30H MOV AH,2 INT 21H MOV DL,' ' MOV AH,2 INT 21H MOV DL,NUM_100 ADD DL,30H MOV AH,2 INT 21H MOV AH,4CH INT 21H CODE ENDS END START Mov SS,AX
Mov DS,AX
Jmp Begin
Char0 DB 0
intCount DB 0
Table DB N+1,?,N Dup(0)
strMessage DB 'Please input chars',10,13,36
Begin:
Lea DX,strMessage Mov AH,9
Int 21H ; 提示输入字符串
Lea DX,Table Mov AH,10
Int 21H ; 得到字符串
Push DX Call SubProc Exit0: Mov AH,4CH Int 21H Main EndP
SubProcProc Near Pop AX Pop BX Push AX
Inc BX ; 得到输入的实际字符串的长度的地址
Mov AX,BX ; 备份地址, 供判断用!
Add BL,[BX] ; 得到该字符串的最后一个字符的地址 Push BX ; 保存地址
Inc BX ; 地址预先加一 Sub0:
Dec BX ; 地址减一
Cmp BX,AX ; 是否地址已经超出范围?
Jz Sub4 ; 是
Cmp Byte Ptr [BX],0 ; 该地址是否有字符?
Jnz Sub1 ; 有
Jmp Sub0 Sub1:
Cmp Char0,0 ; 判断是否已有字符要记数?
Jnz Sub2 ; 有
MovCH,BytePtr [BX]
Mov Char0,CH ; 没有, 置初始字符. Sub3:
Mov Byte Ptr [BX],0 ; 清空该字符
IncintCount ; 加一 Jmp Sub0 Sub2:
MovCH,BytePtr [BX]
Cmp Char0,CH ; 判断该地址的字符是否要记数的字符?
Jnz Sub0 ; 不是
Jmp Sub3 Sub4:
Cmp Char0,BytePtr 0 Jz Ret0
Push
AX ; 保存ax Pop BX MovCL,intCount Mov CH,0
Push
CX ; 字符的个数
Call
HexToDec ; 转换 Mov AH,2 Mov DL,10 Int 21H Mov DL,13 Int 21H Mov DL,Char0
Int 21H ; 显示该字符 Mov DL,'='
Int 21H ; 显示“=”号
Call ShowNumber Mov Char0,0 Mov intCount,0
Pop AX ; 得到ax Pop
BX ; 得到地址 Dec BX Push BX
Cmp AX,BX ; 是否所有的字符已经判断完了? Jnz Sub5 Ret0:
Ret Sub5: Inc BX Jmp Sub0
SubProcEndP ;16进制转换成10进制 HexToDecProc Near Pop BX
Pop
AX ; 要转换的16进制数.
Push
BX ; 保存sp Xor BX,BX Hex0: Cmp AX,0AH
Jb Hex1 ; 已经比10小了,不用再减了!
Sub AX,0AH Add BX,10H Cmp BL,0A0H
Jb Hex0 Add BX,100H
Xor BL,BL
Mov CL,BH And CL,0FH Cmp CL,0AH Jb Hex0
Add BH,010H And BH,0F0H
Jmp Hex0 Hex1:
Add
BX,AX ; 转换到此结束! Pop AX Push
BX ; 保存结果. Push AX Ret HexToDecEndP
ShowNumberProc Near Pop AX Pop BX Push AX Mov DL,BH
And DL,0F0H Mov CL,4 Shr DL,CL
Or DL,30H
Mov AH,2
Int 21H ; 显示千位 Mov DL,BH
And DL,0FH Or DL,30H
Int 21H ; 显示百位 Mov DL,BL Mov CL,4 Shr DL,CL
Or DL,30H
Int 21H ; 显示十位 Mov DL,BL
And DL,0FH Or DL,30H
Int 21H ; 显示个位 Ret ShowNumberEndP Code0 EndS
End Start