logo资料库

循环结构与子程序设计实验.docx

第1页 / 共14页
第2页 / 共14页
第3页 / 共14页
第4页 / 共14页
第5页 / 共14页
第6页 / 共14页
第7页 / 共14页
第8页 / 共14页
资料共14页,剩余部分请下载后查看
汇编语言程序设计 实验报告 实验名称 循环结构与子程序设计实验 班 学 姓 日 成 级 号 名 期 绩 评 阅 人 软件学院
一、 实验目的与意义 汇编语言程序设计实验(上机练习)是必不可少的学习环节之一,也是检验掌握汇编语言 程序设计知识的手段之一。 通过上机练习,可以加深对课程知识的理解和掌握,通过本次实验,加深了对循环程序 设计的理解,掌握单重和多重循环的程序设计,掌握子程序和宏指令的程序的汇编,了解子 程序和宏指令给程序编写带来的方便。 二、 实验环境 操作系统:Windows xp 测试软件:editplus 3,masm 5.0 上机地点:综合楼 311 三、 实验的预习内容 ⑴ 实验前必须掌握循环控制指令,串操作指令的汇编格式和操作功能,了解循环的控 制方法以及编制循环结构程序的技巧。 ⑵ 对于实验 5,就是要掌握单重和多重循环指令的使用,灵活的运用寄存器,以及可 能会用到子程序的内容。 ⑶ 对于实验 6,明确子程序的定义与调用、主程序子程序之间的转返过程,掌握宏汇 编提供的部分条件汇编与宏指令命令及其使用方法。 四、 实验的步骤与调试方法 ⑴ 实验 1 的步骤:先将 5 个数分别定义到数据段中,然后将数据的首地址送到 si 中, 将数据个数送到 cx 中,然后一个一个的跟 64H(100)做比较,若有相等的,直接输出“Y”, 若比了 5 次都没找到相等,输出“N”,换一种做法就是使用 LODSB 指令,简化程序,LODSB 就相当于 AL<---DS:[SI],SI<---SI+1。 ⑵ 实验 2 的步骤:先定义一个子程序,功能是输出两数相乘的结果,这样在之后的程 序中就可以调用这个子程序来输出结果,然后分别利用寄存器来输出被乘数、乘号、乘数、 等号和结果,其中内层循环是一个数的运算,而外层循环则是数的更换。 ⑶ 实验 3 的步骤:想定义 2 个宏指令分别是求绝对值和求和,求绝对值是一个一个的 取数,遇到真的到下一个,遇到负的用 0 减去本身,求和是分别取 sum 数据段和当前数据 段的 1 字节的数进行相加,将加得的结果存到 sum 中去,这样就要调 2 次子程序。而使用 宏指令的时候,则简化了求和的方法,只要调用 1 次求和的宏指令就好了。 DW 13h,22h,-6h DW 12h,41h,2h Dw 3 DW 20 dup(?) ⑷ 异常与调试方法: DATA1 DATA2 LEN SUM 单个数据都定义成字类型的了,数的大小和性质都不对了,对于多个数组成一个数,要 每一个单个数必须是字节类型的,这样组成的一个数据才与用数据定义伪指令定义出来的具 有相同的性质与特性。改正如下: ;测试数据 ;数据长度 ;和 DATA1 DATA2 LEN DB 13h,22h,-6h DB 12h,41h,2h DW 3 ;测试数据 ;数据长度
SUM DB 20 dup(?) ;和 五、 实验数据与实验结果 Exp4 开始的五个数据 15h,0dh,64h,60h,62h,所以有 100,输出“Y” 然后将 64h 改为 52h,结果就是“N”了。 Exp5 输出九九乘法表 Exp6 当三个数分别是 13h,22h,6h 和 12h,41h,02h 时,初始如图所示 运行完后结果如下图,结果应该是 086325h 当输入的数是 13h,22h,-6h 和 12h,41h,-2h 时,初始如图所示
运行完后结果如下图,首先负的数都变成了正的,结果应该还是 086325h 当输入的数变成 13h,22h,-6h 和 12h,41h,2h 时,初始如图所示 运行完后结果如下图所示,也是负的变成了正的,结果还是 086325h 如果使用宏指令,结果是一样的。输入的数分别是 12h,32h,-12h 和 23h,11h,21h 程序完成后,寄存器里的数成为 12h,32h,12h 和 23h,11h,21h 结果是 334335h 六、 实验用程序清单(要有注释) 实验 4(是否存在 100 这个数) 15H,0DH,64H,60H,62H DSEG DATA CNT DW DSEG SSEG SKTOP SSEG CSEG SEGMENT DB 05 ENDS SEGMENT STACK DB 20 DUP(0) ENDS SEGMENT ASSUME ;栈段 ;代码段 CS: CSEG, DS: DSEG ,SS:SSEG START: MOV AX, DSEG MOV DS, AX LEA SI,DATA MOV CX,CNT XOR AX,AX ;将数据的首地址送到 si 里 ;将数据个数送到 CX 中 ;将 AX 清零
AGAIN: MOV AL,[SI] ;将第一个数赋给 AL ;与 64H 比较 ;若相等,则直接转到 disp1,输出 y ;若不相等,看下一个数据,且循环 ;若 5 个数据跟 64H 都不等,则输出 N AGAIN DISP1 CMP AL,64H JZ INC SI LOOP MOV DL,'N' MOV AH,02H INT 21H JMP STOP DISP1: MOV DL,'Y' MOV AH,02H INT 21H STOP: MOV AH,4CH INT 21H CSEG ENDS END START 若换成数据串操作指令 15H,0DH,64H,60H,62H DSEG DATA CNT DW DSEG SSEG SKTOP SSEG CSEG SEGMENT DB 05 ENDS SEGMENT STACK DB 20 DUP(0) ENDS SEGMENT ASSUME ;栈段 ;代码段 CS: CSEG, DS: DSEG ,SS:SSEG START: MOV AX, DSEG MOV DS, AX LEA SI,DATA MOV CX,CNT XOR AX,AX CLD ;指针地址增 1 AGAIN: LODSB ;使用 LODSB 指令,简化程序,LODSB 就相当于 AL<---DS:[SI],SI<---SI+1 CMP AL,64H JZ DISP1 AGAIN LOOP MOV DL,'N' MOV AH,02H
INT 21H JMP STOP DISP1: MOV DL,'Y' MOV AH,02H INT 21H STOP: MOV AH,4CH INT 21H CSEG ENDS END START 实验 5(输出 99 乘法表) DSEG DATA DSEG CSEG DISP 0 SEGMENT DB ENDS SEGMENT ASSUME PROC AX CX DX BX PUSH PUSH PUSH PUSH XOR CX,CX MOV BX,10 S: XOR DX,DX 数是 dx DIV BX INC CX PUSH cmp ax,0 jne s dx CS:CSEG,DS:DSEG ;子程序的功能是输出两数相乘的结果 ;以下四句保存各个寄存器的值 ;初始化 cx=0,cx 记录数的位数 ;初始化 bx=10,bx 作为除数 ;初始化 dx=0,因为以下的除法是 16 位操作数,所以被除 ;而参数是 ax,所以务必清 dx 为 0 ;位数加 1 ;保存余数 ;若 ax=0,则结束 ;否则继续循环 s s1: pop DX ;以下 5 句是逆向取出被保存的余数,并显示 S1 ADD DL,30H MOV AH,02H INT 21H LOOP POP BX POP DX POP CX POP AX RET ;以下 4 句是恢复各个寄存器的值 ;返回
DISP ENDP START: MOV AX,DSEG MOV DS,AX MOV BX,1 MOV CX,1 S0: MOV DL,BL ;以下 4 句是以 10 进制显示 bl ADD DL,30H MOV AH,02H INT 21H MOV DL,'*' MOV AH,02H INT 21H MOV DL,CL ADD DL,30H INT 21H MOV DL,'=' INT 21H MOV AX,BX MOV AL,BL MUL CL CALL DISP MOV DL,20H MOV AH,02H INT 21H INC CX CMP CX,BX JLE S0 MOV DL,0DH MOV AH,02H INT 21H MOV DL,0AH MOV AH,02H INT 21H MOV CX,1 INC BX CMP BX,10 JB S0 ;显示*号 ;以下 3 句以 10 进制显示 cl ;显示=号 ;以下 3 句完成 ax=bl*cl ;调用 disp 函数以 10 进制显示 ax 里的结果 ;输出一个空格 ;以下 3 句检测 cx 是否大于 bx,若真进入下一行 ;以下 6 句输出回车 ;还原 cx=1 ;更新 bx ;bx>9 则结束 ;否则继续
MOV AH,4CH INT 21H ENDS CSEG END START 实验 6(使用子程序的) 13h,22h,-6h 12h,41h,2h segment Db Db 3 dup(?) ends segment stack 20 DUP(?) ends Dseg DATA1 DATA2 LEN Dw SUM Db dseg sseg SK DB sseg CSEG ;定义数据段 ;测试数据 ;数据长度 ;和 ;定义堆栈段 ;堆栈段结束 ;定义代码段 segment assume assume MODULUS PROC MOV CX,LEN cs:CSEG,ds:dseg ss:sseg ;求绝对值 AGAIN1: MOV AL,[SI] ;取数据 AL,AL OR JS Z JNS F Z: mov dL,0 sub dL,[si] MOV [SI],DL F: INC SI AGAIN1 LOOP RET MODULUS ENDP ;负数,跳转 Z ;正数,跳转 F ;负数的话,用 0 减去这个数, ;再把结果返回到[SI]中 ;取下个数据 SUM1 PROC ;数据求和 MOV CX,LEN MOV DI,OFFSET SUM CLC AGAIN2: MOV AL,[SI] ;取数据 MOV BL,[DI] ADC BL,AL MOV [DI],BL ADD SI,1 ADD DI,1 ;相加,求和 ;存入 SUM 单元中 ;取下个数据
分享到:
收藏