《作业与子程序》PPT课件.ppt

上传人:tia****nde 文档编号:11501185 上传时间:2020-04-26 格式:PPT 页数:41 大小:378.50KB
返回 下载 相关 举报
《作业与子程序》PPT课件.ppt_第1页
第1页 / 共41页
《作业与子程序》PPT课件.ppt_第2页
第2页 / 共41页
《作业与子程序》PPT课件.ppt_第3页
第3页 / 共41页
点击查看更多>>
资源描述
1.作业讲评2.子程序:关注入口参数、出口参数、传递方式。特别注意堆栈的使用及其内容。能描述堆栈变化。,本次课内容,统计AX中1的个数送到CL,0的个数送到CH.分析逐位处理,一般可以用移位指令完成.无论哪种移位,所移出的位都会放在CF中.,问题:,“广泛流传”的版本,codesegmentassumecs:codestart:movax,0100100110101001Bxorbx,bxmovcx,16circle:rolax,1,怎么会有两个loopcircle?,jcBitSetincbhloopcirclejmpcountoverBitSet:incblloopcircle,其实16位可以一块送,countover:movch,bhmovcl,blmovax,4c00hint21hcodeendsend,该流程图虽然可行,但仍有以下问题:1.有必要两处判断CX=0吗?2.同样的代码(loopcircle)写了两次.3.分支与循环结构交叉,易出现错误.此流程图需要完善。,CF=0?,BL-BL+1CX-CX-1,Y,N,开始,AX-数CX-16,CX=0?,Y,END,AX左移一位,CX=0?,Y,N,N,BH-BH+1CX-CX-1,CX-BX,circle,BitSet,countover,完善流程图,流程图本身不是目的,而是将想法表达为算法,为编写程序代码做准备。在流程图阶段,应当检查有没有原则性错误。好的流程图不应当出现交叉的程序结构,更不应存在逻辑错误。优化流程图,可以提高代码效率。,该流程图合乎规范,表现在:1.同样的代码(loopcircle)只写了一次,效率提高了.2.分支与循环结构不再交叉,分支结构完全嵌套在循环结构中,不易出现错误.本流程图很容易转换成代码。,CF=0?,BL-BL+1,Y,N,开始,AX-数CX-16,Y,END,AX左移一位,CX=0?,N,BH-BH+1,CX-BX,circle,BitSet,countover,CX-CX-1,Y,修改后的程序,codesegmentassumecs:codestart:movax,0100100110101001Bxorbx,bxmovcx,16circle:rolax,1,分支在循环结构里面,jcBitSetincbhjmpcountoverBitSet:incblcountover:loopcircle,现在程序简洁了,movcx,bxmovax,4c00hint21hcodeendsend,调试程序,1.不要急于输入输出,在DEBUG中也可以查看程序的执行结果,而且更全面。2.记录程序运行的中间结果,分析其是否正确。如果不正确,要找出问题所在。3.尽量列表格说明程序执行情况,用直观的手段说明你的观点。,例,说明刚才程序的执行结果:至少要列举3种情况,串(string):顺序放在内存中一组相同类型数据(字/字节)串操作:对串中的元素进行相同的操作。串操作的寻址方式(隐含):源操作数指针DS:SI目的操作数指针ES:DI(同一段内操作则须ES=DS)每次串操作后自动修改指针SI和DI:字节串操作后自动1,字串操作后自动2(指下一个)CLD令DF=0作,STD令DF=1作。重复前缀:REPCX0则重复执行MOVS/STOSCX减1REPE/REPZCX0ZF=1则重复执行CMPS/SCASCX减1上次比较相等则继续重复直至CX=0为止REPNE/REPNZCX0ZF=0则重复执行CMPS/SCASCX减1上次比较不相等则继续重复直至CX=0为止,3.3.5串操作指令P.67,串操作指令,串是由字节、字、或双字组成的字符或数据序列,存放在存储器中。基本指令集处理的串长度不超过64K。串操作常用于数据块的快速移动、比较、搜索和存取,执行一次操作串中一个元素,配上重复前缀可按条件完成对整个串的操作。,重复前缀,重复前缀指令的名称、汇编格式、重复条件、后续的串指令及操作见下表。重复前缀也是一条指令,但不能单独使用,需加在串操作指令之前,使串操作指令重复或条件重复执行,相当于运行一个循环程序;取串指令LODS一般不加重复前缀,因为重复取出串中的元素送到累加器Acc无意义(后面取出的数冲掉前面取出的数)。,串指令使用的一般方法,设置源串地址,设置目标串地址,设置串长度,设置操作方向DF,串指令,MOVSI,源串首地址(或LEASI,源串),MOVDI,目的串首地址(或LEADI,目的串),MOVCX,串长度,CLD(或STD),加重复前缀或循环编程实现批处理,重复执行?,MOVSB:(ES:DI)(DS:SI),SI1,DI1MOVSW:(ES:DI+1、DI)(DS:SI+1、SI),SI2,DI2例将1000个字符的字符串从内存的BUFFER1搬移到内存的BUFFER2中去。MOVSI,OFFSETBUFFER1;BUFFER1偏移地址送SIMOVDI,OFFSETBUFFER2;BUFFER2偏移地址送DIMOVCX,1000;传送个数送CXCLD;令DF=0,地址自动递增LR:REPMOVSB;重复搬移1000个字节LC:.,3.3.51.串传送指令MOVSB/MOVSW,CLDLR:MOVSBDECCXJNZLRLC:.,用串传送指令实现数据块传送,MOVSB:(ES:DI)(DS:SI),SI1,DI1MOVSW:(ES:DI+1、DI)(DS:SI+1、SI),SI2,DI2例将1000个字符的字符串从内存的BUFFER1搬移到内存的BUFFER2中去。MOVSI,OFFSETBUFFER1;BUFFER1偏移地址送SIMOVDI,OFFSETBUFFER2;BUFFER2偏移地址送DIMOVCX,1000;传送个数送CXCLD;令DF=0,地址自动递增LR:REPMOVSB;重复搬移1000个字节LC:.,3.3.51.串传送指令MOVSB/MOVSW(move),CMPSB:(DS:SI)(ES:DI),SI1,DI1CMPSW:(DS:SI+1、SI)(ES:DI+1、DI),SI2,DI2例比较DEST和SOURCE中的500个字节,找出第一个不相同的字节,如果找到,则将SOURCE中的这个数送AL中。LEADI,DEST;DEST偏移地址送DILEASI,SOURCE;SOURCE偏移地址送SIMOVCX,500;比较次数送CXCLD;令DF=0,地址自动递增REPECMPSB;相同则重复比较直至最后JZNEXT;遇不同或比完:判相同则不存MACH:DECSI;SI退指最后比较不同的那个源数MOVAL,SI;送ALNEXT:.本指令可用来检查两个串是否相等,3.3.52.串比较指令CMPSB/CMPSW(compare),SCASB:(AL)(ES:DI),DI1(search)SCASW:(AX)(ES:DI+1、DI),DI2例在包含100个字符的字符串中寻找第一个回车符CR(其ASCII码为0DH),找到后将其地址保留在(DS:DI)中,并在屏幕上显示“Y”,否则显示“N”。LEADI,STRING;STRING偏移地址送DIMOVAL,0DH;关键字送ALMOVCX,100;比较次数送CXCLD;令DF=0,地址自动递增REPNESCASB;不同则重复比较直至最后JZFOUND;遇相同或比完:判相同则转MOVDL,N;不存在回车:显示“N”JMPDSPYFOUND:DECDI;SI退指找到回车的那个单元MOVDL,Y;显示“Y”DSPY:MOVAH,02H;调用2号软中断输出显示INT21H.本指令用于在串中查找指定的信息,3.3.53.串搜索(扫描)指令SCASB/SCASW,MOVAX,DATAMOVDS,AXMOVES,AX,;在100个字符中找回车符.MODELSMALL;小模式.DATA;数据段STRINGDBHOWDOYOUDO!,0DH,34H,43H,37H,41H,0DH.STACK200;堆栈段,预留200字节.CODE;代码段START:MOVAX,DATAMOVDS,AX;数据段赋值MOVES,AX;附加段赋值MOVDI,OFFSETSTRING;STRING偏移地址送DIMOVAL,0DH;关键字送ALMOVCX,100;比较次数送CXCLD;令DF=0,地址自动递增REPNESCASB;不同则重复比较直至最后JZFOUND;遇相同或比完:判相同则转MOVDL,N;不存在回车:显示“N”JMPDSPYFOUND:DECDI;SI退指找到回车的那个单元MOVDL,Y;显示“Y”DSPY:MOVAH,02H;调用2号软中断输出显示INT21HMOVAH,4CH;返回DOSINT21HENDSTART;汇编结束,LODSB:(AL)(DS:SI),SI1LODSW:(AX)(DS:SI+1、SI),SI2例内存中以BUFFER为首址的缓冲区有10个以非压缩型BCD码形式存放的十进制数,它们的值可能是09中的任意一个,将这些十进制数按顺序显示在屏幕上。LEASI,BUFFER;BUFFER偏移地址送DIMOVCX,10;数据个数送CXMOVAH,02H;置2号DOS功能调用CLD;令DF=0,地址自动递增GET:LODSB;用串装入指令取一个BCD码到ALORAL,30H;转换为ASCII码MOVDL,AL;送DLINT21H;输出显示DECCX;循环计数JNZGET;未完继续MOVAH,4CH;返回DOSINT21H.,3.3.54.串装入指令LODSB/LODSW(load)从内存串数据逐个装入到CPU的AL里来,使用重复前缀没有意义,MOVAL,SIINCSI,STOSB:(ES:DI)AL,DI1STOSW:(ES:DI+1、DI)AX,DI2例用STOS指令将字符“#”装入到以AREA为首地址的100个字节中。LEADI,AREALEADI,AREAMOVAX,#MOVAX,#MOVCX,50MOVCX,50CLDCLDREPSTOSWREPSTOSBMOVAH,4CHMOVAH,4CHINT21HINT21HSTOS指令加重复前缀通常用于初始化一个内存区域,3.3.55.串存储指令STOSB/STOSW(store),;习题求100个8位补码数平均值及小于平均值的数的个数.MODELSMALL;小模式.DATA;数据段BMDB34,-38,43,-51,96DUP(?)NEQU4PJDB?XGDB?.STACK200;堆栈段,预留200字节.CODE;代码段START:MOVAX,DATA;数据段赋值MOVDS,AXMOVSI,OFFSETBM;SI指向数组首地址MOVBX,0;累加寄存器清0MOVCX,N;对N个数累加LB1:MOVAL,SI;取当前单字节补码数到ALCBW;扩展为字在AXADDBX,AX;加到BX中INCSI;SI指向下一个数LOOPLB1;循环,MOVAX,BX;累加和送AXMOVCL,N;置除数NIDIVCL;除以+100得平均值于ALCBW;扩展为字在AXMOVPJ,AL;存平均值MOVBL,0;计个数寄存器清0MOVSI,OFFSETBM;SI重新指向数组首地址MOVCX,N;对100个数统计LB2:CMPAL,SI;平均值与当前补码数比较JLELB3;:不计INCBL;当前补码数小:BX计数加1LB3:INCSI;SI指向下一个数LOOPLB2;循环MOVXG,BL;存小于平均值的个数MOVAH,4CH;返回DOSINT21HENDSTART,4.2.5子程序设计P.103,子程序(过程)的定义及结构(设过程名SUB1,NEAR属性),SUB1PROCNEAR;过程定义伪指令PUSHAX;保护现场(子程序中需要改变的寄存器)PUSHFPUSHBX.POPBX;恢复现场POPFPOPAXRET;子程序返回SUB1ENDP过程的类型属性缺省为NEAR(段内),段间调用则为FAR属性,关于子程序的一些要素子程序:保护现场与恢复现场(子程序内会破坏的寄存器);利用主程序传递的入口参数;子程序的处理功能(公用性、专门化);处理结果数据通过出口参数传递给主程序。主程序调用过程:入口参数初始化;调用子程序:CALL过程名;出口参数利用与处理;,4.2.5子程序设计例(一),例在BCDZ单元中有一个2位十进制数的压缩BCD码,试编程将其转换成二进制数,并保存到BINZ单元。分析:子程序SUB1的处理功能:将AL中的2位压缩BCD码转化为二进制数存回AL。入口参数:要转化的单字节压缩BCD码AL出口参数:转化好的二进制结果AL保护现场:F、BX、CX主、子程序共用寄存器:AL,MOVAH,AL;取BCD码MOVBL,ALANDAH,0FH;保留低四位的个位码ANDBL,0FHMOVBL,AH;个位BCD码保存在BLMOVCL,04H;SHRAL,CL;十位BCD码移至低四位MOVBH,10;设乘数10于BHMULBH;AL中十位码乘10ADDAL,BL;加上个位码得二进制结果于AL中,SUB1子程序主体程序段:,本例通过寄存器传递参数!,4.2.5子程序设计例(二),例在一个带有符号的数组中选出绝对值最大的值,并找出该值所在的位置,分别存在MAX和INDEX单元中。分析变量定义及建立的参数表:0000HARRAYDW1,20,-5,;数组假设100个2单元00C8HCOUNTEQU($-ARRAY)/2;计算数组长度(元素个数):0064H00C8HMAXDW?;存放绝对值最大元素的原值00CAHINDEXDB?;存放绝对值最大元素的序号00CBHTAB:DWARRAY,COUNT,MAX,INDEXII表内值:0000H,0064H,00C8H,00CAHBX表内址:以BX取以BX+2取以BX+4取以BX+6取,本例通过建立的参数表传递参数!,MOVDH,1;元素序号跟踪计数初值MOVDL,0;存放序号,清0MOVSI,BX;取数组首址ARRAYMOVCX,BX+2;取数组元素个数COUNTDECCX;循环次数少1LODSW;取首个元素到AXADDAX,0;转化为绝对值JNSNUM0NEGAXMOVDI,AX;首个元素绝对值进最大绝对值寄存器NUM0:LODSW;取DI指向的新一个元素到AX,DI加2ADDAX,0;转化为绝对值JNSNUM0NEGAX,例SUB1子程序主体程序段:,MOVDI,0;极小绝对值,NUM1:CMPDI,AX;与新元素比较JNCNEXT;新元素不大,维持不变,转MOVDI,AX;新元素大则进入DIMOVDL,DH;新元素大则同时记存其序号NEXT:INCDH;元素序号跟踪计数加1LOOPNUM0;未完继续循环MOVSI,BX+6;比完,取最大元素序号INDEX单元地址MOVSI,DL;存最大绝对值元素序号MOVSI,BX;再取数组首址,SI重新指向数组头MOVDH,0;最大绝对值元素序号扩为字:DXSHLDX,1;最大绝对值元素序号乘2ADDSI,DX;相加指向最大绝对值元素MOVAX,SI;取最大绝对值元素原值MOVDI,BX+4;取最大绝对值MAX单元地址MOVDI,AX;存最大绝对值元素值,MOVBX,SI,MOVSI,DX,JGE,增:,BX+SI,SI,例在DAT1和DAT2分别开始的连续8个单元中存放了两个16位十进制数的压缩BCD码,试编程将其求和,并存放在SUM开始的连续10个单元中。主程序:.modelsmall.datadat1db34h,67h,98h,86h,02h,41h,59h,23hdat2db33h,76h,89h,90h,05h,07h,65h,12h,4.2.5子程序设计例(三),sumdb10dup(0).codemovax,datamovds,axmovax,offsetsumpushaxmovax,offsetdat2pushaxmovax,offsetdat1pushax,4.2.5子程序设计例(三续),calladdpmovah,4chint21haddpprocnearpushbpmovbp,spmovcx,8movsi,bp+4movdi,bp+6,4.2.5子程序设计例(三续),本例通过堆栈传递参数或参数地址!(画出参数在堆栈中的位置),movbx,bp+8clcagain:moval,siadcal,didaamovbx,alincsiincdiincbxloopagain,4.2.5子程序设计例(三续),本例通过堆栈传递参数或参数地址!(画出参数在堆栈中的位置),adcbx,0popbpret8addpendpend,4.2.5子程序设计例(三续),BP,断点IP值,DAT1,DAT2,SUM,进入子程序后的SP位置,子程序返回后的SP位置,例编写计算N!的程序。主程序:ALN,CALLFACTDX(AL)!,RESULTDX子程序FACT:求(AL)!DX若:(AL)=0则DX1(0!=1),RET否则:AL值压栈,AL-1AL,CALLFACTDX(AL)!;弹出栈(原AL值)CL,CLDLDXRET,4.2.5子程序设计例(四)递归子程序:在子程序中又调用本子程序,主程序,0!=1DXRET,例编写计算N!的程序运行示意。,子程序FACT:求(AL)!DX,FACT,FACT,FACT,AL=3栈3-1=2ALCALL2!出栈3CLCLDLDX(32=6)RET,AL=2栈2-1=1ALCALL1!出栈2CLCLDLDX(21=2)RET,AL=1栈1-1=0ALCALL0!出栈1CLCLDLDX(11=1)RET,ALN=3CALL3!RESULTDX=6,FACT,画出堆栈内容示意图,并用DEBUG检查。,实验任务1.找出10个有符号字中的最大负数和最小正数。要求:画出流程图,分析问题,给出程序,调试给出结果.2.找出6000060100范围内的全部素数。用一个子程序判断AX中的数是否为素数,主程序调用后找出全部素数。要求分别画出主程序和子程序流程图,给出程序,调试后给出全部素数.你的子程序给出入口参数、出口参数、功能说明、占用资源情况。3.上题用宏完成。比较宏和子程序各有什么优点、缺点。通知:近期会安排一次测验。,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!