汇编语言程序设计第六章-子程序结构_第1页
汇编语言程序设计第六章-子程序结构_第2页
汇编语言程序设计第六章-子程序结构_第3页
汇编语言程序设计第六章-子程序结构_第4页
汇编语言程序设计第六章-子程序结构_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

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

文档简介

1第六章子程序结构6.1子程序的设计方法6.1.1过程定义伪操作格式为:Procedure_namePROCAttributeProcedure_nameENDP…子程序:又称过程,相当于高级语言的过程和函数。优点:程序结构模块化,一次设计屡次使用,实现代码重用。省时省事,省内存。将功能和结构相同的程序段,表示成子程序形式。2子程序指令CALLRET子程序名或地址表达式子程序与主程序可在同一代码段中,也可不在同一代码段中。前者为近调用〔只改变IP指针值〕CALLNEARPTRSUB0后者为远调用〔改变CS和IP两者〕CALLFARPTRSUB1子程序的最后一条指令必须是RET3SUBR1PROCNEARRETSUBR1ENDP

由于MAIN和子程序SUBR1是在同一代码段中,所以SUBR1定义为NEAR属性,这样MAIN中对SUBR1的调用和SUBR1中的RET就都是NEAR属性的。注意:由于程序的主过程,作为DOS调用的一个子过程,因而DOS对MAIN的调用及MAIN中的RET就是FAR属性的。Codsegmend

MAINPROCFARCALLSUBR1

RETMAINENDP…………例:调用程序和子程序在同一代码段中。Cod

ends4上例也可以写成如下的程序MAINPROCFARCALLSUBR1RETSUBR1PROCFARRETSUBR1ENDPMAINENDP也就是说,过程定义可以嵌套,一个过程定义中可以包括多个过程定义。…

…5例调用程序和子程序不在同一个代码段内。

SEGXSEGMENTSUBTPROCFARRETSUBTENDPCALLSUBTSEGXENDS;SEGYSEGMENTCALLSUBTSEGYENDS…

SUBT为一过程,它有两处被调用,分别是它在同一SEGX段内和在另一段内的SEGY,为此SUBT必须具有FAR属性,以适应SEGY段调用的需要。SUBT既有FAR属性,那么不管在哪个段对SUBT进行调用都具有了FAR属性,那就不会出现错误。66.1.2子程序的调用和返回CALL子程序名RET

7PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016H20018H20020H下一页2001AH2001CH2001EH8PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:DX20016HSPCX20018HSPBX2001AHSPAX2001CHSPIP2001EHSPCS20020HSP下一页9PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:DX20016HSPCX20018HBX2001AHAX2001CHIP2001EHCS20020H10PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016HSPCX20018HBX2001AHAX2001CHIP2001EHCS20020H11PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016HSP20018HBX2001AHAX2001CHIP2001EHCS20020H12PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016HSP20018H2001AHAX2001CHIP2001EHCS20020H13PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016HSP20018H2001AH2001CHIP2001EHCS20020H14PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016HSP20018H2001AH2001CH2001EHCS20020H15PROCFARPUSHAXPUSHBXPUSHCXPUSHDXPOPDXPOPCXPOPBXPOPAXRETENDPSUBTSUBT…

6.1.3保存与恢复存放器先看一个例子〔如图〕:20016H20018H2001AH2001CH2001EH20020H再看一遍16注意:(1)哪些存放器必须保存,哪些不必要或不应保存(2)一般来讲,子程序中用到的存放器是应该保存的(3)如果存放器在主程序与子程序之间传递参数,那么不用保存,特别是返回结果的情况。176.1.4子程序的参数传送6.1.4.1通过存放器传送参数例6.3十进制数到十六进制数转换程序。程序要求从键盘取得一个十进制数,然后该数以十六进制数形式在屏幕上显示出来。18下面的程序是子程序DEC2BIN,实现从键盘取得十进制数并把它转换为二进制数。;PROCEDURETOCINVERTDECONKEYBDTOBINARY;RESULTISLEFTINBXREGISTERDEC2BINprocfarmovbx,0;clearBXfornumber;Getdigitfromkeybroad,converttobinary开始调用DEC2BIN调用CRLF调用BIN2HEX调用CRLF结束从键盘取得十进制数,保存在BX中显示回车和换行用十六进制形式显示BX中的数19movintsubjlcmpjgcbwxchgmovmulxchgaddjmpretendpah,121hal,30hexital,9dexitax,bxcx,10dcxax,bxbx,axnewchar;keybroadinput;callDOS;ASCⅡtobinary;jumpif<0;isit>9d?;yes,notdecdigit;byteinALtowordinAX

newchar:;(digitisnowinAX);multiplynumberinBXby10decimal;tradedigit&number;put10decinCX;numbertimes10;tradenumber&digit;adddigittonumber;getnextdigit;returnfromdecibin;endofdecibinprocexit:DEC2BIN20;------------------------------------;回车换行CRLFPROCFARPUSHAXPUSHDXPUSHFMOVDL,0DHMOVAH,2INT21HMOVDL,0AHMOVAH,2INT21HPOPFPOPDXPOPAXRETCRLFENDP216.1.4.2如过程和调用程序在同一源文件中,那么过程可直接访问模块中的变量。6.1.4.3如过程和调用程序不在同一源文件中,那么它们之间的通信问题将在以后讨论。6.1.4.4通过地址表传送变量地址。采用地址表传送变量法的程序实现:MOVMOVMOVMOVCALLTABLE,OFFSETNUMTABLE+2,OFFSETNTABLE+4,OFFSETTOTALBX,OFFSETTABLEPROADD;prog_segsegmentorg100hassumecs:prog_seg,ds:prog_seg,es:prog_seg22procmovmovmovmovcallintendpprocpushpushpushpushmovmovmovmovxorneartable,offsetarytable+2,offsetcounttable+4,offsetsumbx,offsettableproadd20hnearaxcxsidisi,[bx]di,[bx+2]cx,[di]di,[bx+4]ax,axmainmain;;puttheaddressesofary,;countandsuminparameter;table;putaddroftableinBX;callproadd;definesubprocedure;saveregister;gettheaddrofarray,the;valueofcount,andthe;addrofresult;clearAX…proadd23addaddloopmovpoppoppoppopretendpdwdwdwdwendsendax,[si]si,2next[di],axdisicxaxdup(?)100?dup(?)mainnext:proaddarycountsumtableprog_seg;addtheelementofthe;arraytoAX;returnresult;restoreregister;return;endsubprocedure;reserve100wordforary;and1wordforcountand1;wordforsum;reserve3wordsforparameter;addresses;;;246.1.4.5通过堆栈传递参数或参数地址通过堆栈传送参数地址法的程序实现如下所示〔子程序没有给出〕:segmentdwdwdwendssegmentdup(?)Word;教材P132endsarycountsumdwlabelpram_segpram_segstack_segtosstack_seg100dup(?)100?;definedatasegment;;25segmentprocmovmovmovpushsubpushmovmovmovpushcode1mainstart:;setupSSandSPregister;setupstackforreturn;setDSregistertocurrentdatasegment

assumecs:code1,ds:parm_seg,ss:stack_seg;definecodesegment;mainpartofprogram;startingexecutionaddress;saveolddatasegment;putzeroinAX;saveitonstack;datasegmentaddr;intoDSregister;pushaddrofaddronto;stackax,stack_segss,axsp,offsettosdsax,axaxax,pram_segds,axbx,offsetarybx;26movpushmovpushcallretendpendsbx,offsetcountbx,bx,offsetsumbxfarptrproaddmaincode1…;;pushaddrofcountonto;stack;pushaddrofsumonto;stack;276.3子程序举例

HEX2DEC是一个把十六进制数转换成十进制数的程序。要求把从键盘输入的0~FFFFH的十六进制正数转换成十进制数并从屏幕上显示出来。程序由HEX2BIN和BIN2DEC两个主要的子程序组成,由于主程序和子程序在同一模块中,因而省略了对存放器的保护和恢复工作,子程序之间的变量传输那么采用存放器传送的方式进行。程序实现如以下图所示:;HEX2DEC;convertshexonkeybroadtodeconscreen;EQUSTATEMENTSGOHEREdisplaykey_inDoscallHEX2DECMainprogramequequequsegment2h1h21h;videooutput;keybroadinput;DOSinterruptnumber;definesegment;28main;Mainpartofprogramlinkssubroutinestogetherstart:;setupstackforreturn;MAINPARTOFPROGRAMGOESHERE;;mainprocassumecs:HEX2DECpushsubpushcallcallcallcalljmpretendpfardsax,axaxHEX2BINCRLFBIN2DECCRLFmain;mainpartofprogram;startingexecutionaddress;saveolddatasegment;putzeroinAX;zeroonstack;keybroadtobinary;printcr&lf;binarytodecimal;printcr&lf;getnextinput;returntoDOS;endofmainpartofprogram29HEX2BIN;Subroutinetocinverthexonbinary;resultisleftinBXregister;Getdigitfromkeybroad,converttobinarynewchar:;notdigit(0to9),maybeletter(atof)procmovintsubjlcmpjlsubcmpjlcmpjgenearah,key_indoscallal,30hexital,10dadd_toal,27hal,0ahexital,10hexit;definesubprocedure;keybroadinput;callDOS;ASCⅡtobinary;jumpif<0;isit>9d?;yes,soit’sdigit;converASCⅡ(小写)tobinary;isit<0ahex?;yes,notletter;isit>0fhex?;yes,notlettermovbx,0;clearBXfornumber30add_to:exit:HEX2BINBIN2DEC;SubroutinetoconvertbinarynumberinBXtodecimalonconsolescreenmovshlmovaddjmpretendpprocmovcallmovcallmovcallmovcallmovcallret;ishexdigit,addtonumberinBXcl,4bx,clah,0bx,axnewcharnearcx,10000ddec_divcx,1000ddec_divcx,100ddec_divcx,10ddec_divcx,1ddec_div;setshiftcount;rotateBX4bit;zerooutAH;adddigittonumber;getnextdigit;returnfromHEX2BIN;endsubprocedure;divideby10000;divideby1000;divideby100;divideby10;divideby1;returnfrombinidec31dec_div;SubroutinetodividenumberinBXbynumberinCX;printquotientonscreen;(numberatorin(DX,AX),denominCX);printthecontentofDLonscreendec_divBIN2DECENDPprocmovmovdivmovmovaddmovintret

endpnearax,bxdx,0cxbx,dxdl,aldl,30hah,displaydoscall;numberlowhalf;zeroouthighhalf;dividebyCX;remainderintoBX;quotientintoDL;converttoASCⅡ;displayfunction;callDOS;returnfromdec_div;;32procmovmovintmovmovintretendpendsendneardl,0ahah,displaydoscalldl,0dhah,displaydoscallstart;linefeed;display;callDOS;carriagereturn;displayfunction;callDOS;returnfromcrlf;endofcodesegment;endassemblyCRLF;printcarriagereturnandlinefeed;CRLFHEX2DEC;;336.4DOS系统功能调用(P471)DOS系统功能调用的使用方法有以下几种:1〕2〕3〕4〕在AH存放器中存入所要调用功能的功能号;根据所调用功能的规定设置入口参数;用INT21H指令转入子程序入口;相应的子程序运行完后,可以按规定取得出口参数;34作业:5.4试编写一段程序,要求比较两个字符串STRING1和STRING2所含字符是否相同,假设相同那么显示‘MATCH’,假设不相同那么显示‘NOMATCH‘。(1)要点:用REPECMPSB指令。(2)当两个字符串长度不相等时,比较的含义根据具体情况来定义,比方:判断长度不相等时,那么直接判断为两个字符串不相同。35程序实现如以下图所示:;DOS16位实模式EXE程序.MODELSMALL.586;-----------堆栈段-----------.STACK300H;堆栈大小为300H;--------------------------------;-----------数据段------------.DATA;<<请在下面定义变量>>

MATCH_NOTDB"NOMATCH!$"MATCH_OKDB"MATCH!$"STRING1DB"STRING"STRING2DB"STRING"STR1DB?;<<请在上面定义变量>>;--------------------------------36;-----------代码段------------.CODEStart:;取得段地址

movAX,@DATAmovDS,AXmovES,AX;所有串指令的SI必须是DS,而DI必须是ES;<<请将您的代码写在下面>>MainPROCFAR

;①取得字符串的偏移地址

LEASI,STRING1LEADI,STRING2

;②计算字符串长度

MOVCX,STR1-STRING2CLD;③setDF=0REPECMPSB;④JNZNO_MATCH;不相等

JMPMATCH;相等REPECX=0或ZF=0串指令CX=CX-1Y退出37NO_MATCH:LEADX,MATCH_NOTJMPDISPLAYMATCH:LEADX,MATCH_OKDISPLAY:;显示比较结果movAH,09hint21hmovAH,4chint21hMainENDP;<<请将您的代码写在上面>>;--------------------------------ENDStart38作业5.5:试编写一段程序,要求能从键盘接收一个个位数N,然后响铃N次(响铃的ASCII码为07H)。开始调用InputNum从键盘取得一位个位数,保存在BX中延时一秒BX=‘q’?SUB_DELAY结束Y响铃一次NCX=0?NY39程序实现如以下图所示:;DOS16位实模式EXE程序.MODELSMALL.586;-----------堆栈段-----------.STACK300H;堆栈大小为300H;--------------------------------;-----------数据段------------.DATA;<<请在下面定义变量>>

TIPSDB"Pleaseinputanumberbetween0-9(qorQindicatesEXIT):$";<<请在上面定义变量>>;--------------------------------;-----------代码段------------.CODEStart:movAX,@DATAmovDS,AX40;<<请将您的代码写在下面>>MainPROCFAR;读入数字

CALL InputNum;判断是否为非法字符

CMP BX,-1DJE EXITMOV CX,BXBELL:MOV DL,07H ;响铃为07HMOV AH,2 ;输出字符功能:AH=02INT 21H;延迟一秒

CALL SUB_DELAY

LOOP BELLEXIT:MOV AH,4CHINT 21HRETMainENDP41;读取一个数字保存在BX中InputNum PROCFARPUSH AXPUSH DXPUSHFINPUT:

;显示提示

CALL Crlf

;MOV AH,09HINT 21H;读入字符

MOV AH,01HINT 21H;判断是否输入Q或qCMP AL,'Q'JE EXIT_NONE

CMP AL,‘q’

JE EXIT_NONELEADX,TIPS;判断是否在0-9之间

;JL INPUTCMP AL,9DJG INPUTCBWMOV BX,AX

CALL CrlfJMP RETURNEXIT_NONE:MOV BX,-1DRETURN:POPFPOPDXPOPAXRETInputNum ENDPSUB AL,30H42;**************************************;中断号:;AH:2CH;功能:取时间;调用参数:无;返回参数:CH:CL=时:分;DH:DL=秒:1/100秒;该程序中只用到DH(即秒),来实现程序延迟1秒.;程序通过一个循环检测下一秒是否到来,具体如下:;***********************************;过程名:延迟子程序;功能:程序延迟一秒钟;返回:无;***********************************SUB_DELAYPROCFARPUSHAXPUSHBXPUSHCXPUSHDXPUSHF43MOV AH,2CHINT 21HINC DH ;系统秒数个数加1MOV BL,DHCMP BL,3CH ;如果是60JNE SUB_TIMERXOR BL,BL ;BL置0SUB_TIMER:MOV AH,2CHINT 21H ;获取系统时间CMP BL,DH ;JE SUB_RET ;如果到了下一秒,那么返回JMP SUB_TIMERSUB_RET: POPFPOP DXPOP CXPOP BXPOP AXRETSUB_DELAYENDP446.5多模块之间的参数传送问题引用符号在源模块中的声明:

PUBLICsymbolname[,…]引用符号在调用模块中声明:

EXTRNsymbolname:type[,…]45方法①(详见例子6

温馨提示

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

评论

0/150

提交评论