一、实验目的1、掌握子程序有关基本知识,学会子程序设计方法;2、掌握主程序与子程序之间的调用关系及调用方法;3、掌握汇编语言字符串处理方法;4、掌握字符串的输入输出程序设计方法;5、掌握数制转换程序实现方法。
二、实验软硬件环境1、硬件环境:惠普64 位一体化计算机及局域网;2、软件环境:windows 8,红蜘蛛管理系统,MASM for Windows。
三、实验相关知识把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就性成子程序。
子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率。
1) 子程序的定义语句格式汇编语言子程序以proc 语句行开始,以endp 语句行结束。
如:过程名PROC near[或far]过程体..........................过程名ENDP在主程序中用CALL 过程名调用。
主程序和子程序之间传递参数通常通过栈来进行,当然也可以用某些缺省的寄存器或内存来传递。
但以通过栈来传递参数程序的通用性最强。
2) 子程序调用说明子程序从PROC 语句开始,以ENDP 语句结束,程序中至少应当包含一条RET 语句用以返回主程序。
在定义子程序时,应当注意其距离属性:当子程序和调用程序在同一代码段中时,用NEAR 属性;当子程序及其调用程序不在同一个代码段中时,应当定义为FAR 属性。
当由DOS 系统进入子程序时,子程序应当定义为FAR 属性。
为执行子程序后返回操作系统,在子程序的前几条指令中设置返回信息。
3) 子程序使用中的问题A、主程序调用子程序是通过CALL 指令来实现的。
子程序执行后,通过RET 指令,返回主程序调用指令CALL 的下一条指令,继续执行主程序。
一个子程序可以由主程序在不同时刻多次调用。
如果在子程序中又调用了其他的子程序,则称为子程序的嵌套。
特别是当子程序又能调用子程序本身时,这种调用称为递归。
B、调用子程序时寄存器及所用存储单元内容的保护。
如果子程序中要用到某些寄存器或存储单元时,为了不破坏原有的信息,要将寄存器或存储单元的原有内容压栈保护,或存入子程序不用的寄存器或存储单元中。
C、用于中断服务的子程序则一定要把保护指令安排在子程序中,这是因为中断是随机出现的,因此无法在主程序中安排保护指令。
D、调用程序在调用子程序时需要传送一些参数给子程序,这些参数是子程序运算中所需要的原始数据。
子程序运行后要将处理结果返回调用程序。
原始数据和处理结果的传递可以是数据,也可以是地址,统称为参数传递。
E、参数传递必须事先约定,子程序根据约定从寄存器或存储单元取原始数据(称入口参数);进行处理后将处理结果(称出口参数)送到约定的寄存器或存储单元,返回到调用程序。
参数传递一般有下面三种方法:用寄存器传递:适用于参数传递较少、传递速度快的情况;用堆栈传送:适用于参数传递较多、存在嵌套或递归的情况;用存储单元传送:适用于参数传递较多时,但传递速度较慢。
4) 子程序调用的现场保护与恢复保护现场:在子程序设计时,CPU 内部寄存器内容的保护和恢复。
一般利用堆栈实现现场保护和恢复的格式,过程名PROC near[或far]PUSH AXPUSH BXPUSH DX........................POP DXPOP AXRET过程名ENDP5) 键盘输入输出方法汇编语言的数据输入和输出形式如下:A、单个字符数据的输入输出;B、字符串数据的输入输出。
上述通过DOS 功能调用来实现,具体方法如下:A、单个字符输入。
单个字符输入利用DOS 的1 号功能调用实现。
MOV AH,1INT 21H键盘输入的数据以ASCII 码形式存储在AL 寄存器中。
B、单个字符输出。
单个字符输出利用DOS 的2 号功能调用实现。
MOV DL,’?’MOV AH,2INT 21H单个字符输出时将输出字符的ASCII 码放在DL 寄存器中。
C、字符串输入。
键盘输入一串字符串可以利用DOS 的10(或0A)号功能调用来实现。
BUF DB 100 ;预定义最大输入字符个数DB ? ;实际输入字符个数,系统自动统计DB 100 DUP (?) ;存放所输入字符串数据缓冲区........................MOV DX,OFFSET BUFMOV AH,0AHINT 21HA、字符串输出。
字符串输出可由DOS 9 号功能调用来实现。
BUF DB ‘HELLO BIT56$’........................MOV DX,OFFSET BUFMOV AH,9INT 21H四、实验内容1) 编写程序,现有一组字符串为data,name,time,file,code,path,user,exit,quit,text,请编写程序从键盘输入4 个字符的字符串,若存在将其修改为disk, 并将结果在显示器上显示。
2) 编写程序,现有一组字符串为ram,yes,red,the,get,for,and,key,not,may,请编写程序将他们按ASCII 大小排序,并在显示器上显示。
3) 编写程序,现有一组字符串为data,name,time,file,code,path,user,exit,quit,text,请编写程序从键盘输入4 个字符的字符串,若存在将其删除, 并在显示器上显示。
4) 编写程序把从键盘输入的四位十六进制数,转换为十进制形式在屏幕上打印出来。
5) 从键盘输入(显示提示)十个2 位十进制数(正数)到内存中,按从小到大排序,然后把该数以十六进制形式在屏幕上打印出来。
五、程序清单及结果分析1、DATAS SEGMENTBUF DB'data,name,time,file,code,path,user,exit,quit,text$'INPUT DB 10DB?DB 10 DUP('$')DATAS ENDSSTACKS SEGMENTSTACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKSSTART:MOV AX,DATASMOV DS,AXLEA DX,INPUTMOV AH,0AHINT 21HMOV AH,2MOV DL,0AHINT 21HMOV CL,10MOV BL,4LEA SI,BUFLEA DI,INPUT+2COMP:MOV DL,BUF[DI]MOV DH,BUF[SI]CMP DL,DHJNZ NEXTJZ NEXTSINEXTSI:INC SIINC DIDEC BLJZ CHANGEJNZ COMPNEXT:MOV AL,11SUB AL,CLMOV BH,5MUL BHMOV SI,AXLEA DI,INPUT+2MOV BL,4DEC CLJZ OVERJNZ COMPCHANGE:MOV BUF[SI-4],'d'MOV BUF[SI-3],'i'MOV BUF[SI-2],'s'MOV BUF[SI-1],'k'OVER:LEA DX,BUFMOV AH,09INT 21HMOV AH,4CHINT 21HCODES ENDSEND START2、按ASCII码降序排列DATAS SEGMENTBUF DB'ram,yes,red,the,get,for,and,key,not,may$' DATAS ENDSSTACKS SEGMENTSTACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKSSTART:MOV AX,DATASMOV DS,AXLEA DX,BUFMOV AH,09INT 21H;MOV DL,0AHMOV AH,02INT 21HMOV BL,0AHL:MOV CX,9CALL COMPAREDEC BLJNZ LLEA DX,BUFMOV AH,09INT 21HMOV AH,4CHINT 21HCOMPARE PROCCOMP:CMP CL,0JZ RETURNMOV AX,9SUB AL,CLMOV DL,4MUL DLMOV SI,AXMOV DL,BUF[SI+4]DEC CLCMP BUF[SI],DLJZ COMPNEXTJL CHANGEJA COMPCOMPNEXT:INC SIMOV DL,BUF[SI+4]CMP BUF[SI],DLJZ COMPNEXTJL CHANGEJA COMPCHANGE:MOV AX,8SUB AL,CLMOV DL,4MUL DLMOV SI,AXMOV DL,BUF[SI]MOV DH,BUF[SI+4]MOV BUF[SI],DHMOV BUF[SI+4],DLINC SIMOV DL,BUF[SI]MOV DH,BUF[SI+4]MOV BUF[SI],DHMOV BUF[SI+4],DLINC SIMOV DL,BUF[SI]MOV DH,BUF[SI+4]MOV BUF[SI],DHMOV BUF[SI+4],DLJMP COMPRETURN:RETCOMPARE ENDP CODES ENDSEND START按ASCII码降序排列3、DATAS SEGMENTBUF DB'data,name,time,file,code,path,user,exit,quit,text$$$$$' INPUT DB 10DB?DB 10 DUP('$')DATAS ENDSSTACKS SEGMENTSTACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKSSTART:MOV AX,DATASMOV DS,AXMOV ES,AXLEA DX,INPUTMOV AH,0AHINT 21HMOV DL,0AHMOV AH,2INT 21HLEA DI,INPUT+2MOV BL,10MOV CX,4CLDCOMP:MOV AL,10SUB AL,BLMOV DL,5MUL DLMOV SI,AXREPE CMPSBJZ DELETLEA DI,INPUT+2MOV CX,4DEC BLJZ OVERJNZ COMPDELET:MOV AL,BUF[SI+1]MOV BUF[SI-4],ALMOV AL,BUF[SI+2]MOV BUF[SI-3],ALMOV AL,BUF[SI+3]MOV BUF[SI-2],ALMOV AL,BUF[SI+4]MOV BUF[SI-1],ALADD SI,5DEC BLJNZ DELETOVER:MOV AH,9LEA DX,BUFINT 21HMOV AH,4CHINT 21HCODES ENDSEND START4、DATAS SEGMENTDATAS ENDSSTACKS SEGMENTSTACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS INPUT PROCMOV BX,0MOV CL,4GETCHAR:MOV AH,1INT 21HCMP AL,30HJB OVERREADCMP AL,39HJA CHARSUB AL,30HJMP PLUSCHAR:CMP AL,41HJB OVERREADCMP AL,'F'JA OVERREADSUB AL,41HADD AL,0AHPLUS:MOV AH,0SHL BX,CLADD BX,AXJMP GETCHAROVERREAD:RETINPUT ENDP;;;;;;;;;;;;;CHANGE PROCMOV CX,10000DCALL DIV_MOV CX,1000DCALL DIV_MOV CX,100DCALL DIV_MOV CX,10DCALL DIV_MOV CX,1CALL DIV_RETCHANGE ENDP ;;;;;;;;;DIV_ PROCMOV DX,0MOV AX,BXDIV CXMOV BX,DXMOV DX,AXADD DL,30HMOV AH,2INT 21HRETDIV_ ENDP START:MOV AX,DATASMOV DS,AXCALL INPUTCALL CHANGE MOV AH,4CHINT 21H CODES ENDSEND START5、DATAS SEGMENTBUF DB 30DB?BUF1 DB 30 DUP (?)BUF2 DB 10 DUP (0)DATAS ENDSSTACKS SEGMENTSTA DB 100 DUP (?)STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS INPUT PROCLEA DX,BUFMOV AH,0AHINT 21HMOV DL,0AHMOV AH,02HINT 21HRETINPUT ENDPTURN PROC NEARLEA SI,BUF1LEA DI,BUF2MOV BL,10MOV CX,10L:MOV AL,[SI]SUB AL,30HMUL BLINC SIADD AL,[SI]SUB AL,30HMOV [DI],ALINC DIADD SI,2LOOP LRETTURN ENDPORDER PROC NEARMOV CX,9LEA SI,BUF2LEA DI,BUF2INC DIL1:PUSH CXPUSH SIPUSH DICALL COMPAREPOP DIPOP SIPOP CXLOOP L1RETORDER ENDPCOMPARE PROC NEAR GO:MOV AL,[SI]MOV BL,[DI]CMP AL,BLJA CHANGEJBE L2L2:INC SIINC DILOOP GORETCHANGE:MOV [SI],BLMOV [DI],ALJMP L2COMPARE ENDPOUTPUT PROC NEARMOV SI,OFFSET BUF2MOV CX,10ON:MOV BX,0MOV DL,[SI]SHR DL,1SHR DL,1SHR DL,1SHR DL,1THEN:CMP DL,10JB IS_NUMADD DL,37HJMP L3IS_NUM:ADD DL,30HL3:MOV AH,02HINT 21HINC BXCMP BX,2JZ L4MOV DL,[SI]AND DL,0FHJMP THENL4:MOV DL,20HMOV AH,02HINT 21HINC SILOOP ONRET OUTPUT ENDP START:MOV AX,DATASMOV DS,AXMOV AX,STACKSMOV SS,AXMOV ES,AXCALL INPUTCALL TURN CALL ORDERCALL OUTPUTMOV AH,4CHINT 21H CODES ENDSEND START六、实验心得经过这次实验,我学会了调用子程序的方式,用CALL调用子程序,通过调用子程序可以化简程序。