第六章子程序结构_第1页
第六章子程序结构_第2页
第六章子程序结构_第3页
第六章子程序结构_第4页
第六章子程序结构_第5页
已阅读5页,还剩56页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章子程序结构§6.1子程序的设计方法一、子程序指令二、子程序的调用与返回三、现场的保护与恢复四、子程序参数的传递一、子程序指令子程序是完成特定功能的一段程序当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行当运行完子程序功能后,采用RET返回指令回到主程序继续执行一、子程序指令—调用指令CALL指令分成4种类型(类似JMP)CALLlabel ;段内调用、直接寻址CALLr16/m16 ;段内调用、间接寻址CALLfarptrlabel ;段间调用、直接寻址CALLfarptrmem ;段间调用、间接寻址CALL指令需要保存返回地址:段内调用——偏移地址IP入栈SP←SP-2,SS:[SP]←IP段间调用——偏移地址IP和段地址CS入栈SP←SP-2,SS:[SP]←CSSP←SP-2,SS:[SP]←IP一、子程序指令—返回指令根据段内和段间、有无参数,分成4种类型RET ;无参数段内返回RETi16 ;有参数段内返回RET ;无参数段间返回RETi16 ;有参数段间返回需要弹出CALL指令压入堆栈的返回地址段内返回——偏移地址IP出栈IP←SS:[SP],SP←SP+2段间返回——偏移地址IP和段地址CS出栈IP←SS:[SP],SP←SP+2CS←SS:[SP],SP←SP+2一、子程序指令—返回指令RET的参数 RETi16 ;有参数返回RET指令可以带有一个立即数i16,则堆栈指针SP将增加,即SP←SP+i16这个特点使得程序可以方便地废除若干执行CALL指令以前入栈的参数二、子程序的调用与返回CALLlabel主程序RET子程序回到CALL指令后的指令处

——返回地址二、子程序的调用与返回

—书写形式(同一代码段内)二、子程序的调用与返回

—书写形式(不同代码段)三、现场的保护与恢复现场:主程序转向子程序之前,其所使用的一些资源的状态(如标志位、R/M等)子程序与主程序分别编制,通常会导致使用的资源发生冲突而影响主程序在调用子程序之后的正确执行方法:利用堆栈在主程序中进行在子程序中进行三、现场的保护与恢复

—在主程序中进行……PUSHBXPUSHAXCALLSUB1POPAXPOPBX……注意:

进栈/出栈的顺序保护与恢复的对象: 主程序用到的存有数据、中间结果且在CALL指令后还要用到的R/M三、现场的保护与恢复

—在子程序中进行SUB1 PROC PUSHBX PUSHAX …… POPAX POPBX RETSUB1ENDP注意:

进栈/出栈的顺序保护与恢复的对象: 子程序用到的R/M四、子程序参数的传递入口参数(输入参数):主程序提供给子程序出口参数(输出参数):子程序返回给主程序参数的形式:①数据本身(传值)②数据的地址(传址)传递的方法:①寄存器②变量③堆栈例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示对两个数进行转换、显示的工作是相同的,没有必要重复编写,以子程序的形式来完成显示子程序需被告知:被显示内容的起始位置被显示内容的长度被转换的数及其长度存放结果的起始位置转换子程序需被告知:例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-1.asm)方法一:用寄存器传递参数显示子程序:DI:被显示内容的起始位置指针CX:被显示内容的长度BX:被转换的数CX:被转换数的长度DI:存放结果的起始位置指针转换子程序:

;转换子程序BINASC PROCREP1: ROLBX,1 MOVDL,BL ANDDL,01H ADDDL,30H ;屏蔽除最低位外的其他位

MOV[DI],DL INCDI LOOPREP1 RETBINASC ENDPBLBHDLDI;显示子程序DISP PROCREP2: MOVAH,2 MOVDL,[DI] INT21H INCDI LOOPREP2 MOVDL,0AH ;设置显示后的光标位置

MOVAH,2 INT21H MOVDL,0DH MOVAH,2 INT21H RETDISP ENDPDSEG SEGMENTPARA'DATA' BIN1 DB35HBIN2 DW0AB48HASCBUF DB20HDUP(?)DSEG ENDSCSEG SEGMENTPARA'CODE' ASSUMECS:CSEG,DS:DSEG,SS:SSEGMAIN PROCFAR MOVAX,DSEG MOVDS,AX MOVBH,BIN1 MOVCX,8 LEADI,ASCBUF PUSHDI PUSHCX CALLBINASC POPCX POPDI PUSHDI CALLDISP POPDI ADDDI,10H MOVBX,BIN2 MOVCX,16 PUSHDI PUSHCX CALLBINASC POPCX POPDI CALLDISP

MOVAX,4C00H INT21H;转换子程序BINASC PROCREP1: ROLBX,1 MOVDL,BL ANDDL,01H ADDDL,30H ;屏蔽除最低位外的其他位

MOV[DI],DL INCDI LOOPREP1 RETBINASC ENDP;显示子程序DISP PROCREP2: MOVAH,2 MOVDL,[DI] INT21H INCDI LOOPREP2 MOVDL,0AH ;设置显示后的光标位置

MOVAH,2 INT21H MOVDL,0DH MOVAH,2 INT21H RETDISP ENDPMAIN ENDP CSEG ENDS ENDMAIN ;setentrypoint例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-2.asm)方法二:用堆栈传递参数方法二之主程序段 MOVAH,BIN1 ;要转换的数进栈 PUSHAX LEADI,ASCBUF ;地址指针 PUSHDI MOVAX,8 ;长度 PUSHAX CALLBINASC ;调用转换子程序 MOVAX,BIN2 PUSHAX ADDDI,10H PUSHDI MOVAX,16 PUSHAX CALLBINASC;转换并显示子程序BINASC PROC PUSHDI PUSHAX PUSHBX PUSHCX PUSHDX PUSHBP MOVBP,SP MOVBX,[BP+18] MOVDI,[BP+16] MOVCX,[BP+14]REP1: ROLBX,1 MOVDL,BL ANDDL,01H ;屏蔽除最低位外的其他位 ADDDL,30H

MOV[DI],DL MOVAH,6 INT21H INCDI LOOPREP1

MOVAH,6 MOVDL,0AH INT21H MOVAH,6 MOVDL,0DH INT21H

POPBP POPDX POPCX POPBX POPAX POPDI

RET6BINASC ENDPBP=SPBX地址IP长度进入子程序时的SPAXDIBIN1CXDXBPBP+14BP+16BP+18方法二之堆栈§6.2嵌套与递归子程序嵌套:子程序调用其他子程序,嵌套层数取决于堆栈的大小32K(基本不受限制)递归:子程序调用自己,该情况要合理设置出口参数,否则会造成程序死锁§6.3子程序举例例6.3十进制到十六进制数的转换

(从键盘取得一个十进制数,然后把该数以十六进制的形式在屏幕上显示出来)例6.3十进制到十六进制数的转换(6-3-1.DOC)转换方法:‘1234’((((0*10+1)*10)+2)*10+3)*10+4从最高位开始:累加和*10+本位的权值十六进制数显示的实现BHH4BHL4BLH4BLL44BHH4BHL4BLH4BLL4BHH4AL从最高位开始;例6-3,十进制到十六进制数的转换SSEG SEGMENTPARASTACK'STACK' DW100HDUP(0)SSEG ENDSDSEG SEGMENTPARA'DATA' DSEG ENDSCSEG SEGMENTPARA'CODE’ ASSUMECS:CSEG,DS:DSEG,SS:SSEGMAIN PROCFAR MOVAX,DSEG ;MAKENECCESSARYINITALIZALITION MOVDS,AXREPEAT: CALLDECIBIN CALLCRLF CALLBINIHEX CALLCRLF JMPREPEAT MOVAH,0AH INT21H

MOVAX,4C00H ;RETURNDOS INT21HMAIN ENDP ;从键盘获得十进制数并将其转换成十六进制数置于BX中DECIBIN PROC MOVBX,0NEWCHAR: MOVAH,1 INT21H SUBAL,30H JLEXIT ;非十进制数则退出

CMPAL,9 JGEXIT CBW XCHGAX,BX ;将原有的数*10后加新输入的数

MOVCX,10 MULCX XCHGAX,BX ADDBX,AX JMPNEWCHAREXIT: RETDECIBIN ENDP;将BX中的十六进制数转换成相应的ASCII码显示在屏幕上BINIHEX PROC MOVCH,4 ;共四位十六进制数ROTATE: MOVCL,4 ROLBX,CL MOVAL,BL ;从最高位开始,将其移位至BX,AL的低4位

ANDAL,0FH ADDAL,30H CMPAL,3AH JLPRINTIT ADDAL,7 ;如为A-F的处理PRINTIT: MOVDL,AL MOVAH,2 INT21H DECCH JNZROTATE RETBINIHEX ENDPCRLF PROC MOVDL,0AH MOVAH,2 INT21H MOVDL,0DH MOVAH,2 INT21H RETCRLF ENDPCSEG ENDS ENDMAIN;SETENTRYPOINT例6.8把以ASCII码形式表示的十进制数转换成二进制数(6-8-2.asm,6-8-1.asm增强型编程)程序限制:转换后的二进制数不超过16位转换方法:‘12345’5*1 =

5 5*01H =5H4*10 =40 4*0AH =28H3*100 =300 3*64H =12CH2*1000 =2000 2*3E8H =7D0H1*10000 =10000 1*2710H =2710H求和 =12345 求和 =3039H从最低位开始增强功能的过程定义伪操作格式:PROCNAME PROC[ATTRIBUTESFIELD][USESREGISTERLIST][,PARAMETERFIELD] ……PROCNAME ENDPATTRIBUTESFIELD: DISTANCE LANGUAGETYPE VISIBILITY PROLOGUE增强功能的过程定义伪操作例6.8

.MODELSMALL .STACK64 .DATAASCVAL DB'12345'BINVAL DW? .CODEMAIN PROCFAR MOVAX,@DATA MOVDS,AX LEABX,ASCVAL PUSHBX LEABX,BINVAL PUSHBX CALLCONVASCBIN

MOVBX,BINVAL CALLBINIHEX

MOVAX,4C00H INT21HMAIN ENDPCONVASCBIN PROCPASCALUSESAXBXCXSIDI,PAR1:WORD,PAR2:WORD LOCALASCLEN:WORD,MULFACT:WORD MOVBX,10 MOVSI,PAR1 MOVDI,PAR2 SUBDI,SI MOVASCLEN,DI MOVCX,DI ADDSI,CX DECSI MOVMULFACT,1 MOVDI,PAR2 MOVWORDPTR[DI],0 NEXT: MOVAL,[SI] ANDAX,000FH MULMULFACT ADD[DI],AX MOVAX,MULFACT MULBX MOVMULFACT,AX DECSI LOOPNEXT RETCONVASCBIN ENDP BINIHEX PROC MOVCH,4 ROTATE: MOVCL,4 ROLBX,CL MOVAL,BL ANDAL,0FH ADDAL,30H CMPAL,3AH JLPRINTIT ADDAL,7 PRINTIT: MOVDL,AL MOVAH,2 INT21H DECCH JNZROTATE RET BINIHEXENDP ENDMAIN ;SETENTRYPOINT例:6.9十六进制到十进制数的转换把从键盘输入的0-FFFF的十六进制正数转换成十进制数并在屏幕上显示出来Hexibin:键盘输入十六进制数其数值在BX中crlf:回车换行Binidec:十六进制到十进制转换并显示例6.9DISP EQU2HKEY_IN EQU1HDOSCALLEQU21HSSEG SEGMENTPARASTACK'STACK' DW100HDUP(0)SSEG ENDSCSEG SEGMENTPARA'CODE' ASSUMECS:CSEG,SS:SSEGMAIN PROCFAR MOVCL,4 CALLHEXIBIN ;调用十六进制数输入子程序 CALLCRLF

CALLBINIDEC ;调用十六进制到十进制转换子程序 CALLCRLF JMPMAIN MOVAX,4C00H INT21HMAIN ENDP 例6.9 ;十六进制输入并转换为十六进制数值子程序,十六进制数值在BX中 HEXIBIN PROC MOVBX,0NEWCHAR: MOVAH,KEY_IN INTDOSCALL SUBAL,30H JLEXIT ;非十六进制数值输入则结束输入 CMPAL,10 JLADD_TO SUBAL,27H CMPAL,10H JGEEXIT ADD_TO: SHLBX,CL ;新输入的数值(在AL的低四位上)加入到BX的低四位中 MOVAH,0 ADDBX,AX JMPNEWCHAR EXIT: RET HEXIBIN ENDP例6.9 ;十六进制到十进制转换并显示子程序 ;被除数是BX,除数分别是10000,1000,100,10,1,; ;商是十进制;数,余数作为下次的被除数 BINIDEC PROC MOVCX,10000D CALLDEC_DIV MOVCX,1000D CALLDEC_DIV MOVCX,100D CALLDEC_DIV MOVCX,10D CALLDEC_DIV MOVCX,1 CALLDEC_DIV RET BINIDEC ENDP DEC_DIV PROC MOVAX,BX MOVDX,0 DIVCX MOVBX,DX MOVDL,AL ADDDL,30H MOVAH,DISP INTDOSCALL RET DEC_DIV ENDP例6.9CRLF PROC MOVDL,0AH MOVAH,DISP INTDOSCALL MOVDL,0DH MOVAH,DISP INTDOSCALL RETCRLF ENDP

CSEG ENDS ENDMAIN例6.10一个简单的信息检索系统数据区里有10个不同的信息,编号为0-9,每个信息包括30个字符。编制程序从键盘接收0-9之间的编号,然后在屏幕上显示相应编号的信息内容。(6-10.asm,6-10.doc)SSEG SEGMENTPARASTACK'stack' DW100HDUP(0)SSEG ENDSDSEG SEGMENTPARA'Data' THIRTY DB?MESG0 DB'Thisismessage0-------------'MESG1 DB'Thisismessage1-------------'MESG2 DB'Thisismessage2-------------'MESG3 DB'Thisismessage3-------------'MESG4 DB'Thisismessage4-------------'MESG5 DB'Thisismessage5-------------'MESG6 DB'Thisismessage6-------------'MESG7 DB'Thisismessage7-------------'MESG8 DB'Thisismessage8-------------'MESG9 DB'Thisismessage9-------------'LEN EQUMESG1-MESG0ERRMSG DB'error!!!invilidparameter!!'DSEG ENDS例6.10:1/3CSEG SEGMENTPARA'CODE' ASSUMECS:CSEG,DS:DSEG,SS:SSEGMAIN PROCFAR MOVAX,DSEG MOVDS,AX MOVTHIRTY,LENBEGIN: MOVAH,1 INT21H SUBAL,'0’ JCERROR CMPAL,9 JAERROR

PUSHAX MOVDL,0AH CALLDISPCHAR MOVDL,0DH CALLDISPCHAR POPAX

MOVBX,OFFSETMESG0 MULTHIRTY ADDBX,AX CALLDISP JMPBEGIN

ERROR: MOVBX,OFFSETERRMSG CALLDISP

MOVAX,4C00H INT21H例6.10:2/3 DISP PROC MOVCX,30 DISP1: MOVDL,[BX] CALLDISPCHAR INCBX LOOPDISP1 MOVDL,0AH CALLDISPCHAR MOVDL,0DH CALLDISPCHAR RET DISP ENDPDISPCHAR PROC MOVAH,2 INT21H RETDISPCHAR ENDP

MAIN ENDP CSEG ENDS ENDMAIN ;SETENTRYPOINT例6.10:3/3例6.11人名排序程序。从键盘键入最多30个人名,当所有人名都进入后,按字母上升的次序将人名排序,并在屏幕上显示已排序后的人名(6-11)

b10read:输入子程序(所占空间固定,但要将多出部分清为空格)D10stor:将本次输入存储到表中(DI中是在表中起始地址的指针,同时计存储到表中的名字的个数)g10sort:排序(冒泡排序)H10xch:交换表中相邻项的顺序K10disp:显示已排序的名字表Q10clr:清屏Q20curs:设置光标位置 DSEG SEGMENTPARA'DATA' NAMEPAR LABELBYTEMAXLEN DB21NAMELEN DB?NAMEFLD DB21DUP(?) CRLF DB13,10,'$'ENDADDR DW? MESG1 DB'NAME?','$'NAMECTR DB0NAMETAB DB20DUP(20DUP(''))NAMESAV DB20DUP(?),13,10,'$'S DB0 DSEG ENDS CSEG SEGMENTPARA'CODE' ASSUMECS:CSEG,DS:DSEG MAIN PROCFAR MOVAX,DSEG MOVDS,AX MOVES,AX例6.11:1/6 CLD LEADI,NAMETAB ;表首址作为目的串的首址

CALLQ10CLR CALLQ20CURS A20LOOP: CALLB10READ ;调输入子程序

CMPNAMELEN,0 JZA30 CALLD10STOR ;存储

JMPA20LOOP A30: CALLQ10CLR CALLQ20CURS CMPNAMECTR,1 JBEA40 CALLG10SORT A40: CMPNAMECTR,0 JBEEXIT CALLK10DISP EXIT: MOVAX,4C00H INT21H MAIN ENDP例6.11:2/6 ;名字输入子程序B10READ PROC MOVAH,9 LEADX,MESG1 INT21H MOVAH,0AH LEADX,NAMEPAR INT21H MOVAH,9 LEADX,CRLF INT21H MOVBH,0 ;缓存区的空余部分填空格 MOVBL,NAMELEN

MOVCX,21 SUBCX,BX B20: MOVNAMEFLD[BX],20H INCBX LOOPB20 RETB10READ ENDP ;名字存储子程序D10STOR PROC ;名字个数计数器加1 INCNAMECTR CLD LEASI,NAMEFLD MOVCX,10 REPMOVSW RETD10STOR ENDP例6.11:3/6;排序子程序G10SORT PROC SUBDI,40 MOVENDADDR,DI G20: MOVS ;交换标志清0 LEASI,NAMETAB G30: MOVCX,20 MOVDI,SI ADDDI,20 MOVAX,DI MOVBX,SI REPECMPSB JBEG40 CALLH10XCH ;调用交换顺序子程序 G40: MOVSI,AX CMPSI,ENDADDR JBEG30 CMPS JNZG20 RETG10SORT ENDP例6.11:4/6 ;交换表的内容 H10XCH PROC MOVCX,10 LEADI,NAMESAV MOVSI,BX REPMOVSW MOVCX,10 MOVDI,BX REPMOVSW

MOVCX,10 LEASI,NAMESAV REPMOVSW

MOVS RET H10XCH ENDP ;显示已排序的名字表 K10DISP PROC LEASI,NAMETAB K20: LEADI,NAMESAV MOVCX,10 REPMOVSW MOVAH,9 LEADX,NAMESAV INT21H DECNAMECTR JNZK20 RET K10DISP ENDP例6.11:5/6 ;清屏子程序 Q10CLR PROC MOVAX,0600H MOVBH,61H SUBCX,CX MOVDX,184FH INT10H RET Q10CLR ENDP ;设置光标位置子程序Q20CURS PROC MOVAH,2 SUBBH,BH SUBDX,DX INT10H RETQ20CURS ENDP CSEG ENDS ENDMAIN ;SETENTRYPOINT例6.11:6/6§6.4DOS系统功能调用裸机ROM-BIOSDOS功能调用汇编语言程序系统功能调用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论