···························································· 实验 三 experiment3 结构程序设计 汇编语言程序和采用其他高级语言编写的程序的结构一样,主要有顺序 结构、分支结构、循环结构、子程序结构和宏结构5种(上机实验环境和实验步 骤见主教材第11章)。 任务1 顺序和分支结构程序设计 顺序结构程序是最简单的一种程序结构,即写在前面的指令先执行,后面 的指令后执行,适用于简单的应用场合。分支结构程序可根据条件进行选择。 任务目标 1.牢记转移指令和比较指令的格式及用法。 2.正确描述汇编语言宏观架构,建立初步的汇编思维。 3.正确描述分支结构的执行过程,进一步加深对分支结构的理解。 4.正确使用顺序和分支结构解决实际问题,养成良好的编程习惯,具备程 序员的职业素养。 5.对程序进行查错与排错,具备一定的程序调试能力和技巧。 6.熟练保存和备份程序,树立保密意识,养成知保密、懂保密、善保密的良 好习惯。 9 8 ◆汇编语言上机指导(微课版) 任务实施 通过对主教材的学习,编写具有顺序结构和分支结构的程序以解决实际 问题。 【任务1.1】 有3个有符号数,分别为10H、67H 和02H,编写源程序计算 VAL=67H/02H+10H。 分析:在数据段中定义3个字节变量,依次存储为10H、67H 和02H。除 数02H 为字节类型,被除数67H 须扩展为字类型,商为字节类型,最后结果为 字节类型。 源程序compute.asm 如下。 DATA SEGMENT A DB 10H,67H,02H VAL DB ? DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV AL,A+1 ;AL=67H CBW ;AX=0067H MOV BL,A+2H ;BL=02H IDIV BL ;AX 除以BL,商送AL,余数送AH MOV CH,A ;CH=10H ADD AL,CH ;AL=CH+AL MOV VAL,AL ;将AL 中的内容传送至VAL 指向的字节单元 MOV AH,4CH INT 21H CODE ENDS END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 实验三1.1 ◆ 实验三 结构程序设计99 compt.sm 。 uea 第二步:用汇编程序MASM.EXE 汇编compueasm 源程序,严重错误 t. 个数为0表示汇编成功,否则需要修改源程序;继续执行第二步,直到严重错 误个数为0。 第三步:用链接程序LINK.ompueoj。 EXE 链接文件ct.b 第四步:用调试程序DEBUG.ompueee,使用反汇编命 EXE 调试文件ct.x 令U可以查看数据段段基址和一些无用指令。 第五步:指令执行前,用R命令观察源程序中使用的寄存器AX 、DS 、BL 和CH 中的内容为AX=FFFFH 、DS=075AH 、BL=00H 和CH=00H(这样 指令执行前后寄存器中的内容可以对比)。 ◆ 100 汇编语言上机指导(微课版) 指令执行前,用D命令观察数据段0000H 、0002H 和0003H 指向的字节 单元中的内容分别为10H 、67H 和02H(这样指令执行前后数据段中的内容可 以对比)。 第六步:用T命令执行第1、2条指令后,AX=076AH,DS=076AH 。 用T命令执行第3条指令后,AL=67H 。 用T命令执行第4条指令后,被除数扩展为字类型,AX=0067H 。 用T命令执行第5条指令后,除数传送至BL=02H 。 用T命令执行第6条指令后,AX/BL=0067H/02H,商为33H 。 用T命令执行第7条指令后,将0000H 指向的字节单元中的内容传送至 CH,CH=10H 。 实验◆三 结构程序设计1 01 用T命令执行第8条指令后,将AL和CH 求和,结果传送至AL。 用T命令执行第9条指令后,将AL中的内容传送至0003H 指向的字节 单元。 用T命令执行第10条指令后,AH=4CH;用P命令执行INT21H 结束 程序,返回操作系统。 【任务1.2】 设TABLE表存放1~9的平方,NUM 存放1~9中的任意 一个数,编写源程序,将NUM 中数的平方传送至BL。 分析:该题须在TABLE 表中查找NUM 中数的平方,可将TABLE 表的首 地址传送至BX,NUM 中的数传送至AL,然后用XLAT 指令即可实现该任务。 源程序xlat.asm 如下。 DATA SEGMENT TABLE DB 0,1,4,9,16,25,36,49,64,81 NUM DB 5 DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA 实验三1.2 1 02 ◆汇编语言上机指导(微课版) START: MOV AX,DATA MOV DS,AX LEA BX,TABLE ;TABLE 首地址传送至BX,BX=0000H MOV AL,NUM ;NUM 指向的字节单元中的内容传送至AL,AL=5 XLAT TABLE ;将BX+AL 指向的字节单元中的内容传送至AL,AL=25(19H) MOV BL,AL ;BL=19H MOV AH,4CH INT 21H CODE ENDS END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 xlat.asm。 第二步:用汇编程序MASM.EXE汇编源程序xlat.asm,严重错误个数为 0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重错误个 数为0。 第三步:用链接程序LINK.EXE链接文件xlat.obj。 第四步:用调试程序DEBUG.EXE调试文件xlat.exe,使用反汇编命令U 可以查看数据段段基址和一些无用指令。 第五步:指令执行前,用R 命令观察源程序中使用的寄存器AX、DS和 BX中的内容为AX=FFFFH、DS=075AH、BX=0000H(这样指令执行前后 寄存器中的内容可以对比)。 ◆ 实验三 结构程序设计103 指令执行前,用D命令观察数据段TABLE 表0000H~0009H 指向的字 节单元中的内容分别为00H~51H,NUM 字单元中的内容为05H(这样指令 执行前后数据段中的内容可以对比)。 第六步:用T命令执行第1、2条指令后,AX=076AH,DS=076AH 。 用T命令执行第3、4条指令后,BX=0000H,AL=05H 。 用T命令执行第5、6条指令后,将BX+AL=0000H+05H=0005H 指 向的字节单元中的内容19H 传送至AL,AL=19H,BL=19H 。 1 04 ◆汇编语言上机指导(微课版) 用T命令执行第7、8条指令后,程序正常结束。 【任务1.3】 设X和Y字节单元分别存放有符号数89H 和02H,编写源 程序,求两个数中的最小数并传送至MIN字单元。 分析:89H 和02H 为有符号数,89H 转换为二进制是10001001B,最高 位为1,则为负数;02H 转换为二进制数是00000010B,最高位为0,则为正数; 所以最小数为89H。 源程序min.asm 如下。 DATA SEGMENT X DB 89H Y DB 02H MIN DB ? DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV AL,X ;X 指向的字节单元中的内容89H 传送至AL MOV BH,Y ;Y 指向的字节单元中的内容02H 传送至BH CMP AL,BH ;AL-BH, JG L1 ;AL 大于BH,跳转到L1,BH 为小数 MOV MIN,AL JMP NEXT L1: MOV MIN,BH NEXT: MOV AH,4CH INT 21H CODE ENDS 实验三1.3 实验◆三 结构程序设计1 05 END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 min.asm。 第二步:用汇编程序MASM.EXE汇编源程序min.asm,严重错误个数为 0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重错误个 数为0。 第三步:用链接程序LINK.EXE链接文件min.obj。 第四步:用调试程序DEBUG.EXE调试文件min.exe,使用反汇编命令U 可以查看数据段段基址和一些无用指令。 第五步:指令执行前,用R 命令观察源程序中使用的寄存器AX、DS和 BH 中的内容为AX=FFFFH、DS=075AH、BH=00H(这样指令执行前后寄 存器中的内容可以对比)。 指令执行前,用D命令观察数据段X、Y 和MIN 字节单元中的内容分别 为89H、02H 和00H(这样指令执行前后数据段中的内容可以对比)。 第六步:用T命令执行第1、2条指令后,AX=076AH,DS=076AH。 106 ◆ 汇编语言上机指导(微课版) 用T命令执行第3、4条指令后,AL=89H,BH=02H 。 用T命令执行第5~7条指令后,MIN 字节单元存放最小数89H 。 用T命令执行第8、11 和12 条指令后,程序正常结束。 实验◆三 结构程序设计1 07 【任务1.4】 从键盘输入1~3中任意一个数,编写源程序,在屏幕上分别 显示“1OK”“2OK”或“3OK”;如果输入其他字符,则显示“*”。 分析:该题有3种情况,相当于有3个分支,如图3.1所示。 图3.1 3种情况 源程序output.asm 如下。 DATA SEGMENT STR DB "OK$" DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV AH,01H ;将功能号01H 传送至AH INT 21H ;实现从键盘输入数据传送至AL CMP AL,'1' ;AL-'1' JL L1 ;AL 低于'1',跳转到L1,图3.1①输出* CMP AL,'3' ;AL-'3' JA L1 ;AL 高于'3',跳转到L1,图3.1③输出* L1: MOV DL,'*' MOV AH,02H INT 21H 实验三1.4 1 08 ◆汇编语言上机指导(微课版) NEXT: MOV AH,4CH INT 21H CODE ENDS END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 output.asm。 第二步:用汇编程序MASM.EXE汇编源程序output.asm,严重错误个 数为0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重 错误个数为0。 第三步:用链接程序LINK.EXE链接文件output.obj。 第四步:程序中有输出指令,可直接执行可执行文件,输出结果。 知识拓展 1.BUF 字节单元中有一个有符号数,判断其正负,若为正数,则显示 “+”;若为负数,则显示“-”;若为0,则显示0。 2.设W、X、Y、Z和V是字节变量,计算(X×Y+360-Z)/V,并将结果传 送至W。 实验◆三 结构程序设计1 09 任务2 循环结构程序设计 任务目标 1.牢记循环指令、串操作和比较指令的格式及用法。 2.正确描述循环结构的执行过程,进一步加深对循环结构的理解。 3.正确使用循环结构解决实际问题,树立“不积跬步,无以至千里;不积 小流,无以成江海”的思想。 任务实施 通过前面的学习,编写具有循环结构的程序以解决实际问题。 【任务2.1】 X字节单元中的内容为83H,编写源程序,将其二进制数显 示到屏幕上。 分析:83H 转换为二进制数是10000011B,先显示高位,再显示低位。可 采用SHL指令一位一位地移出,然后调用02H 号功能显示输出;但是02H 号 功能只能显示输出字符型数据,所以须得到0和1的ASCII码30H 和31H。 如图3.2所示,循环移动8次即可将二进制数显示到屏幕上。 图3.2 获得0和1的ASCII码的执行过程 源程序boutput.asm 如下。 DATA SEGMENT X DB 83H 实验三2.1 1 10 ◆汇编语言上机指导(微课版) DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV BL,X ;将X 字节单元中的内容83H 传送至BL MOV CX,8 ;循环次数传送至CX L1: MOV DL,30H ;30H 传送至DL SHL BL,1 ;将BL 中的内容逻辑左移1 位,结果传送至BL ADC DL,0 ;将DL+0+CF 的结果传送至DL MOV AH,02H INT 21H LOOP L1 MOV AH,4CH INT 21H CODE ENDS END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 boutput.asm。 第二步:用汇编程序MASM.EXE汇编源程序boutput.asm,严重错误个 数为0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重 错误个数为0。 第三步:用链接程序LINK.EXE链接文件boutput.obj。 第四步:程序中有输出指令,可直接执行可执行文件,输出结果。 【任务2.2】 BUF字节单元中存放了5个无符号数,求5个数中所有偶数 的累加和。 分析:通过逻辑右移指令将BUF字节单元中的数据向右移动1位,然后 判断CF;如果CF=1,则该数为奇数,否则为偶数。 实验三2.2 实验◆三 结构程序设计1 11 源程序sum.asm 如下。 DATA SEGMENT BUF DB 83H,18H,90H,11H,53H LEN EQU $-BUF ;获得BUF 缓冲区数据个数 DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX MOV AL,00H ;将00H 传送至AL,存放累加和 LEA BX,BUF ;将BUF 缓冲区首地址传送至BX MOV CX,LEN ;将数据个数传送至CX L1: MOV DL,[BX] ;将BX 指向的字节单元中的内容传送至DL SHR DL,1 ;DL 中的内容右移1 位,结果传送至DL JC L2 ;CF=1,说明BX 指向的字节单元中的内容是奇数,跳转到L2 ADD AL,[BX] ;说明BX 指向的字节单元中的内容是偶数,累加到AL L2: INC BX ;BX 自增1,BX 指向下一个字节单元 LOOP L1 MOV AH,4CH INT 21H CODE ENDS END START 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 sum.asm。 第二步:用汇编程序MASM.EXE汇编源程序sum.asm,严重错误个数为 0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重错误个 数为0。 第三步:用链接程序LINK.EXE链接文件sum.obj。 第四步:程序中没有输出指令,用调试程序DEBUG.EXE调试文件sum. ◆ 112 汇编语言上机指导(微课版) exe,使用反汇编命令U可以查看数据段段基址和一些无用指令。 第五步:指令执行前,用R命令观察源程序中使用的寄存器内容(这样指 令执行前后寄存器中的内容可以对比)。 指令执行前,用D命令观察数据段BUF 字节单元中的内容。 第六步:用T命令执行第1次循环,BUF 字节单元中的第1个数据83H 不是偶数,BX 自增1,指向第2个单元。 ◆ 实验三 结构程序设计113 用T命令执行第2次循环,BUF 字节单元中的第2个数据18H 是偶数, 累加到AL,AL=18H,然后BX 自增1,指向第2个单元。 用T命令执行第3次循环,BUF 字节单元中的第3个数据90H 是偶数, 累加到AL,AL=18H+90H=A8H,然后BX 自增1,指向第3个单元。 用T命令执行第4次循环,BUF 字节单元中的第4个数据11 是奇数,BX 自增1,指向第4个单元。 114 ◆ 汇编语言上机指导(微课版) 用T命令执行第5次循环,BUF 字节单元中的第5个数据53H 是奇数, BX 自增1,指向第5个单元,最后所有偶数的累加和为A8H,存放至AL 中。 用T命令执行循环结果,程序正常结束。 实验◆三 结构程序设计1 15 【任务2.3】 BUF字节单元中存放了10个无符号数,在这10个数中查找 是否存在12H,如果12H 存在,则输出YES,否则输出NO。 源程序search.asm 如下。 DATA SEGMENT BUF DB 23H,38H,60H,13H,12H,88H,90H,11H,45H,66H LEN EQU $-BUF MSG1 DB "YES$" MSG2 DB "NO$" DATA ENDS CODE SEGMENT ASSUME CS: CODE,DS: DATA START: MOV AX,DATA MOV DS,AX LEA BX,BUF ;将BUF 缓冲区首地址传送至BX MOV CX,LEN ;将数据个数传送至CX MOV SI,-1 L1: INC SI ;SI 自增1 MOV DL,[BX+SI] ;将BX+SI 指向的字节单元中的内容传送至DL CMP DL,12H ;DL-12H LOOPNE L1 ;结果不相等,继续循环至L1 JZ L2 LEA DX,MSG2 JMP NEXT L2: LEA DX,MSG1 NEXT: MOV AH,09H INT 21H MOV AH,4CH INT 21H CODE ENDS END START 实验三2.3 1 16 ◆汇编语言上机指导(微课版) 上机执行过程如下。 第一步:在编辑工具(记事本、DEVC 或EDIT 等)中输入源程序 search.asm。 第二步:用汇编程序MASM.EXE汇编源程序search.asm,严重错误个数 为0表示汇编成功,否则需要修改源程序,然后继续执行第二步,直到严重错 误个数为0。 第三步:用链接程序LINK.EXE链接文件search.obj。 第四步:程序中有输出指令,可直接执行可执行文件,输出结果。 【任务2.4】 STR1字节单元中存放了字符串“LOVE”,编写源程序,将 STR1串从右到左依次传送至STR2字节单元。 分析:源串STR1的末偏移地址传送至SI,SI=0003H;目的串STR2的 末偏移地址传送至DI,DI=0003H;方向标志DF=1。每重复一次MOVS指 令,SI和DI自减1;重复4次后,STR1中的内容传送至STR2,最后SI和DI 的值为FFFFH。执行过程如图3.3所示。 图3.3 MOVS指令的执行过程 源程序movs.asm 如下。 DATA SEGMENT STR1 DB "LOVE" ;源串 实验三2.4