1、字符串显示功能int 21h ;DOS功能调用mov ax,4c00h返回DOS.exitend三、结果与分析 年 月 实验二 内存数据的移动一、实验要求与目的:1、实验要求:编写程序实现把数据段的字符串数据移动到附加段中。2、实验目的:通过项目学习汇编的数据传送指令和串处理类指令,巩固寻址方式,学习汇编程序设计。二、实验内容:把数据段中以dstring地址标号为开始地址的“hello world!”字符串移动到附加段以sstring地址标号为开始地址中去。2、设计思想:从源串中取一个字符到AL中,然后把刚取到的字符放到目的串指定位置,重复这样的过程,把源串的字符取完为止。程序流程如图2-1所
2、示。图2-1 程序流程图3、程序设计清单:实现这样功能的程序方法很多,下面给出了实现这一功能的完整程序清单(完整段定义格式)。方案一(无聊版):采用的是loop指令,CX为循环次数,当CX为0时退出循环。 加入了换行指令。 用字符串常量$改变字符串,提前终止字符串的输出。程序如下:DSEG SEGMENT dstring DB HELLO,WORLD!,33,33, ;15个字节HELLO,WORLD! dstring_1 db 数据段的字符串: , ;一定要加,表示一个字符串的结束 dstring_2 db 附加段的字符串:在屏幕上显示的字符串DSEG ENDSESEG SEGMENT ss
3、tring DB 15 DUP(?) ;附加段预留15个字节空间ESEG ENDSCODE SEGMENTASSUME CS:CODE, DS:DSEG, ES:ESEG start: MOV AX, DSEG ;程序开始执行的地方 MOV DS, AX ;将DSEG的段地址给ds MOV AX, ESEG MOV ES, AX ;将SSEG的段地址给es LEA SI, dstring ;将dstring的首地址给si LEA DI, sstring ;将sstring的首地址给di MOV CX, 15 ;CX存放loop指令的循环次数S: MOV AL, SI MOV ES:DI, AL
4、 INC DI INC SI LOOP S mov dX,offset dstring_1 MOV AH,09h INT 21H ;输出字符串数据段的字符串: MOV DL,0AH ;输出换行 MOV AH,02H INT 21H mov dX,offset dstring输出字符串: MOV DL,0AH INT 21H ; mov dX,offset dstring_2 INT 21H ;输出字符串dstring_2 mov al, mov es:di-3,al ;将第二个改成以终止字符串的继续输出 MOV AX,ES MOV DS,AX ;将附加段的段地址附给数据段 mov dX,off
5、set sstring显示字符串HELLO,WORLD!注意不是! MOV AX, 4C00HCODE ENDS ;代码段结束END start ;程序结束方案二:采用字符串操作指令movsb,执行di=si。Si与di自动地址改变方向,由std,cld控制。Cx作为计数器,前面应用rep指令重复。13个字节HELLO,WORLD! sstring DB 13 DUP(?) ;附加段留13个字节空间 ASSUME CS: MOV AX, DSEG ; MOV DS, AX ; MOV AX, ESEG MOV ES, AX ;将SSEG的段地址给es LEA SI, dstring ; LEA
6、 DI, sstring ; MOV CX, 13 ;CX存放rep指令的重复次数 cld ;将DF位清零,则di与si自增 rep movsb ;执行di=si MOV DS,AX ; 方案三:采用是cmp与ja跳转指令来实现数据的移动。, ) ; MOV AX, DSEG ; MOV DS, AX ; MOV ES, AX ; LEA SI, dstring ; LEA DI, sstring ; MOV CX, 13 ;CX存放循环次数 MOV AL, SI DEC CX CMP CX,0 JA S MOV DS,AX ; INT 21H ;CODE ENDS ;END start ;附
7、简化段定义格式如下:.model small ;.486 ;说明使用的80X86微处理指令.data ;定义数据段开始dstring db hello,world!sstring db 13 dup(0) ;使用的同一个数据段.code ;.startup ; mov ax,seg dstring ;=mov ax,data mov ds,ax ;将dstring的段地址附给ds mov es,ax ;为了使用movsb指令,由于两个字符串都在数据段,所以令es=ds lea si,dstring lea di,sstring mov cx,13 ;循环次数 cld rep movsbmov
8、dx,offset sstring mov ah,9 int 21h mov ax,4c00hEnd4、调试过程:(在win7x32下调试的方案二)第1步:进入debug:命令debug+file.exe。第2步:用r命令查看cpu寄存器内容,这一步基本没用。看注意点即可注意:此时并未给ds,es赋值,在ds,es赋值之前有ds=es,cs=ds+10h。第3步:用U命令查看汇编指令。直接暴力输入g 001a 也可,但只适用本程序。第四步:用T命令执行一条机器指令。这里了执行四次。 此时可以看到ds和es已经赋值了,此时来查看内存的内容。注意cs没变。第五步:用d命令查看内存的内容。即查看DS
9、:0 和ES:0输入d 0bc6:0和d 0bc7:0。可以看出已经完成移动了。三、结果与分析没仔细去看为什么0bc6:0010处也有hello,world。我调试过了发现还有,猜测可能与ss的栈有关。四、拓展 用q命令退出debug。 用p命令一次执行完循环。 用g+偏移地址(ip),可以直接执行到上一条指令,即此时IP=ip。教师点评:年 月 日实验三 分支程序结构掌握分支结构程序设计的基本方法;掌握无条件转移指令和条件转移指令的使用;掌握分支结构程序设计的两种基本结构的使用。通过分支程序的设计掌握结构化程序设计方法和常用算法设计。编写程序实现:在数据段中,有一个按从小到大顺序排列的无符号
10、数组,其首地址存放在SI寄存器中,数组中的第一个单元存放着数组长度。在key单元中有一个无符号数,要求在数组中查找是否存在key这个数,如找到,则使CF=0,并在DI中给出该单元在数组中的偏移地址;如未找到,则使CF=1。对于这个表格查找,可以使用顺序查找和折半查找的算法思想。当然顺序查找程序简单,效率不高。而折半查找程序复杂,效率高,但对查找数据要求有序。本项目采用折半查找方式。在一个长度为N的有序数组r中,查找元素k的折半查找算法可描述如下:初始化被查找数组的尾下标,low1,highn。若lowhigh,则查找失败,CF=1,退出程序;否则,计算中点mid(low+high)/2。k与中
11、点元素rmid比较。若k= rmid,则查找成功,结束程序;若k rmid,则转步骤。低半部分查找(lower),highmid-1,返回步骤(2),继续执行。高半部分查找(higher),lowmid+1,返回步骤(2),继续执行3、程序清单(简化段定义格式):.model small .486.stackarray db 13,45,49,54,66,78,83,85,89,94,99,123,233,245key db 40cg1 db finderror1 db failedsstring db 12 dup(?).code .startup mov ax,data ;加载数据 mov
12、 ds,ax mov al,key ;查找关键词送AL lea si,array ;把数组的首地址送SI mov bl,array ;把数组元素个数送BL mov bh,0 ;把数组元素个数送BX inc simain: cmp bx,0 jl error ;转到查找失败程序段 shr bx,1 ;bx除以2 cmp al,bx+si ;mid=bx+si ja higher ;若大于,则转到高半部分 jb lower ;若小于,则转到低半部分 jmp cg ;转到查找成功,无条件转移指令higher: add si,bx ;高半部分 jmp mainlower: add si,0 ;低半部分
13、 dec bxerror: lea dx,error1 ;查找失败,lea取有效地址 mov ah,09h ;字符串显示 jmp s ;直接退出cg: lea dx,cg1 ;查找成功 mov ah,09h ; int 21h stc ;cf置0 mov di,bx+si ;di保存s:附完整段定义 ARRAY DB 13,45,49,54,66,78,83,85,89,94,99,123,233,245 KEY DB 45 CG1 DB ERROR1 DB CSEG SEGMENTCSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV AL,KEY LEA
14、 SI,ARRAY MOV BL,ARRAY MOV BH,0 MAIN: CMP BX,0 JL ERROR SHR BX,1 CMP AL,BX+SI JA HIGHER JB LOWER JMP CG HIGHER: ADD SI,BX JMP MAIN LOWER: ADD SI,0 DEC BX ERROR: LEA DX,ERROR1 MOV AH,09H CLC JMP EXIT CG: LEA DX,CG1 STC MOV DI,BX+SI EXIT: MOV AX,4C00HCSEG ENDS END START此程序在计算中值(mid(low+high)/2)采用了一些技巧
15、。在程序思想的描述上,应该计算出高端地址(high)和低端地址(low),再计算中间地址(mid)。实际上我们需要的是中间地址(mid),没有必要一定要计算出高端地址和低端地址。bx+si表示的是中值地址,cmp al,bx+si 这指令表示ax与中值进行比较。本程序稍作修改,就可实现更广应用。令key=45,输出结果如下: 完整段代码输出结果:实验四 循环程序结构一、实验要求与目的掌握循环结构程序设计的基本方法;了解循环控制的方法(计数、条件和混合)。通过循环程序的设计掌握结构化程序设计方法和循环控制方法的设计。二、实验内容 1、项目要求:编写程序实现1100的累加和求算,结果送到SUM单元
16、中。如果循环次数是已知的,则采用计数控制方法。这里计数法可以是正计数即从1计数到n(图4-1(a)所示);也可以是倒计数法即从n计数到0(图4-1(b)所示)。图4-1 累加和流程图方案一:自减法,用的是LOOP循环中CX的自减。.model small ;注意点与m之间不能有空格.data ;sum dw ?mov ax,data mov ds,ax ;初始化数据段 mov ax,0 ;(ax)0 mov cx,100 ; add ax,cx ;求累加和 LOOP S mov sum,ax ;最终结果送到SUM mov ah,4ch int 21h ;方案二(直观作死板)将结果显示在屏幕上原
17、理如下:5050/1000=商5 余数050050/100=商0 余数5050/10=余数00/1=商加上30h即可得到相应数字的ASCII码,然后在调用DOS命令输出字符即可,汇编所有的字符输出都是ASCII码。4,程序如下:DATA SEGMENTSTRING DB 1+2+3+4+5+.+99+100=$输出字符串,$为结束符DATA ENDS STACK SEGMENT DB 16 DUP(?STACK ENDSCODE,DS:DATA,SS:STACK,ES:DATASTART:MOV AX,DATAMOV DS,AXmov dx,offset STRING mov ah,9int
18、21h ;输出字符串mov ax,0mov bx,0mov cx,100 ;inc bxADD ax,bxLOOP S ;实现从1加到100MOV DX,0 ;除数1000要用16位寄存器存储,但5050用AX就可存储MOV BX,1000 ;除1000DIV BXPUSH DX ;余数在DX中,所以要将DX入栈ADD AL,30H ;商值加48转换成ASCII码MOV DL,AL ;DOS系统功能调用,显示mov ah,02HINT 21HPOP DX ;要将余数DX赋值给AX,以作下次除法mov AX,DX ;除100mov BL,100 div BLPUSH AX ;余数在AX中,所以要
19、将AX入栈求ASCII值mov dl,al ;mov ah,2int 21HPOP AXmov aL,AH ;除10MOV AH,0 ;由于余数只存在AL寄存器中所以要将AH寄存器清0mov bL,10 div bLPUSH AX add al,30H ;除1要将AH寄存器清0mov bL,1 MOV AX,4C00Hint 21h code endsend start三、结果和分析 方案二输出结果:方案二只适用于0-9999范围内,即最高加到140,如果要实现更高位位的话可以修改。实验五 子程序结构掌握子程序指令,了解子程序结构和子程序设计的基本方法。学习汇编的子程序结构和模块0。化程序设计
20、方法。编写程序实现对一个无序排列的无符号数组排序。数组的首地址存放在SI寄存器中,数组中的第一个单元存排序前后都存放着数组长度。对于这个排序问题,我们可以采用基本排序算法(如冒泡排序,简单选择排序,插入排序等),也可以采用高级排序算法(如堆排序,归并排序,快速排序等)。为了使程序简单,本项目采用基本排序的冒泡排序。 简单选择排序的基本思想:对文件进行n-1趟排序,第i趟(i=1,2,.n-1)是在从i到 n的n-i+1个记录中选择关键字最小(最大)的记录,并将它与第i个记录进行交换。这里采用子程序结构,整个程序包括一个主程序和两个子程序,程序流程图如图5-1示。这三个子程序是:XZPX:功能是
21、对数组元素进行降序排序。入口参数:采用寄存器SI传递参数。用了寄存器:AX,BX,CX,DX出口参数:无。 DISPLAY:功能是将数组元素输出在屏幕上显示。DIGITAL_DISPLAY:将数组元素中的数字显示在屏幕上。你也可以定义显示字符串然后调用DOS命令,显示字符。 入口参数: 调用的寄存器:AX,BX,DXARRAY DB 13,65,12,97,68,69,70,71,72,73,98,75,76,77DATA ENDS MOV AX, DATA MOV DS, AX CALL DISPLAY ;显示原数字串 CALL XZPX ;大小排序显示排序后的数字串 JMP EXIT ;退出程序 XZPX PROC NEAR PUSH AX PUSH BX PUSH C
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1