《第6-7章-5 循环程 子程序.ppt》由会员分享,可在线阅读,更多相关《第6-7章-5 循环程 子程序.ppt(40页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第6-7章微型计算机汇编语言及汇编程序章微型计算机汇编语言及汇编程序7.4系统功能调用系统功能调用7.5汇编程序的功能及汇编过程汇编程序的功能及汇编过程7.1宏汇编语言的基本语法宏汇编语言的基本语法7.2伪指令伪指令第第6章章 程序设计程序设计 (顺序、分支、(顺序、分支、循环、子程序循环、子程序)7.3宏指令宏指令7.6汇编语言程序设计汇编语言程序设计第第6章微型计算机的程序设计章微型计算机的程序设计6.1程序设计步骤程序设计步骤1376.2简单程序简单程序1386.3分支程序分支程序1406.4循环程序循环程序1436.5子程序子程序1466.6查表程序查表程序1506.4 循环程序设计
2、循环程序设计循循环环程程序序结结构构是是满满足足一一定定条条件件的的情情况况下下,重复执行某段程序重复执行某段程序循环结构的程序通常有循环结构的程序通常有4个部分:个部分:循循环环初初始始部部分分为为开开始始循循环环准准备备必必要要的的条条件件,如循环次数、循环体需要的数值等如循环次数、循环体需要的数值等 循循环环体体部部分分指指重重复复执执行行的的程程序序部部分分,其其中中包括对循环条件等的修改程序段包括对循环条件等的修改程序段循循环环控控制制部部分分判判断断循循环环条条件件是是否否成成立立,决决定是否继续循环定是否继续循环循环结束处理循环结束处理分析和存放程序的结果分析和存放程序的结果初始
3、化初始化初始化初始化循环体循环体循环体循环体判断判断判断判断结束处理结束处理结束处理结束处理循环控制循环控制循环控制循环控制N NY Y循环控制循环控制循环控制循环控制循环控制循环控制循环结构程序循环结构程序的设计关键是的设计关键是循环控制部分循环控制部分循循环环控控制制可可以以在在进进入入循循环环之之前前进进行行,也也可可以在循环体后进行,于是形成两种结构:以在循环体后进行,于是形成两种结构:“先判断、后循环先判断、后循环”结构结构“先循环、后判断先循环、后判断”结构结构图示图示先循环后判断的循环结构先循环后判断的循环结构 结束结束 初始化初始化 循环的初始状态循环的初始状态 循环体循环体
4、循环的工作部分循环的工作部分及修改部分及修改部分 计数控制循环计数控制循环条件控制循环条件控制循环状态控制循环状态控制循环修改部分修改部分控制条件控制条件Y YN N循环控制方式:循环控制方式:计计数数控控制制事事先先已已知知循循环环次次数数,每每次次循循环环加加或或减减计计数,并进行判定总次数以达到控制循环数,并进行判定总次数以达到控制循环。条条件件控控制制事事先先不不知知循循环环次次数数,在在执执行行循循环环时时判判定定某种条件真假来达到控制循环的目的。某种条件真假来达到控制循环的目的。状状态态控控制制可可事事先先设设定定二二进进制制位位的的状状态态,或或由由外外界界干预、测试得到的开关状
5、态,决定循环与否干预、测试得到的开关状态,决定循环与否。不管哪一种控制循环方式,最终都是要达到不管哪一种控制循环方式,最终都是要达到控制循环的目的。若考虑不周,会造成死循控制循环的目的。若考虑不周,会造成死循环,对这一点要注意。环,对这一点要注意。多重循环多重循环循循环环程程序序分分为为单单循循环环和和多多重重循循环环,两两重重以以上上循循环环称称为为多多重循环重循环1 计数控制循环计数控制循环 计计数数控控制制循循环环利利用用循循环环次次数数作为控制条件作为控制条件易易于于采采用用循循环环指指令令LOOP和和JCXZ实现实现初初始始化化:将将循循环环次次数数或或最最大大循循环次数置入环次数置
6、入CX循环体循环体循循环环控控制制:用用LOOP指指令令对对CX减减1、并判断是否为、并判断是否为0【例【例6.5】求两个多字节数之和。】求两个多字节数之和。这这两两个个数数在在10050H地地址址开开始始的的内内存存单单元元中中,连连续续存存放放,低低位位在在小小地地址址一一端端,结结果果放放在在这这两两个个数数之之后后。设设这这两两个个多多字字节节数数均均为为8个个字节长。字节长。(1)分分析析题题目目:这这是是一一个个重重复复累累加加内内存存单单元元中中数数的的问问题题,因因此此可可以以用用循循环环程程序序形形式式解解决决。因因为为86系系列列指指令令系系统统可可以以16位位处处理理,所
7、所以以,循环次数是循环次数是4次次。(2)程序流程图如图程序流程图如图6.10所示。所示。START:MOVAX,1000HMOVDS,AX;DS1000HMOVSI,50H;第一个数指针第一个数指针SI50HMOVDI,58H;第二个数指针第二个数指针DI58HMOVBX,60H;结果指针结果指针BX60HMOVCX,4;循环次数循环次数CX4CLC ;清进清进位位CF0AA:MOVAX,SI;取一个字到取一个字到AXADCAX,DI;AXAX+DI+CFMOVBX,AX;存一个字到存一个字到BX PUSHF;保护进位保护进位CF ADDSI,2;修改第一个数指针修改第一个数指针 ADDDI
8、,2;修改第二个数指针修改第二个数指针 ADDBX,2;修改结果指针修改结果指针 POPF;恢复标志寄存器恢复标志寄存器 LOOPAA;CXCX-1,若若CX0转转AA HLT;CX0,暂停暂停【例【例6.6】设计一个软件延时程序】设计一个软件延时程序,延时时间约延时时间约1ms左右左右思路:思路:从从手手册册上上可可以以查查得得PUSHF和和POPF指指令令分分别别为为10和和8个个时时钟钟节节拍拍,LOOP BX指指令令为为3.4个个时时钟钟节节拍拍,即即此此循循环环体体需需要要用用10+8+3.421.4拍拍,而而每每个个时时钟钟节节拍拍是是根根据据此此系系统统的的晶晶振振频频率率而而定
9、定的的。假假设设此此系系统统用用的的是是8MHz的的晶晶振振,则则每每个个时时钟钟节节拍拍需需要要0.125s,因因此此我我们们可可以以根根据据下下列列公公式式算算出出循循环环次数:次数:X延时时间延时时间/一次循环时间一次循环时间1ms/21.40.125s374次次换算成十六进制数为换算成十六进制数为176H。P451P451指令表有误指令表有误指令表有误指令表有误注意:时钟频率不同,延时结果不同注意:时钟频率不同,延时结果不同注意:时钟频率不同,延时结果不同注意:时钟频率不同,延时结果不同START:MOV CX,176H;初初始化,设定循环次数始化,设定循环次数CX374LP1:PUS
10、HF;循环体循环体POPFLOOPLP1;CXCX-1,若若CX0转转LP1HLT;暂停暂停如果想再延长如果想再延长1000倍时间倍时间(即延时即延时1s),我们可以采我们可以采用双循环的方法来解决用双循环的方法来解决MOVBX,3E8H;BX1000LP2:MOV CX,176HLP1:PUSHF POPF;延时延时1ms程序段程序段 LOOP LP1 DECBX;BXBX-1JNZLP2;ZF0时,时,转至转至LP2,即即BX0时转时转HLT;暂停暂停内循环是内循环是1ms时间,而在外循环时间,而在外循环中的两条控制指令中的两条控制指令DEC和和JNZ所所对应的时钟节拍分别为对应的时钟节拍
11、分别为2个和个和4个个,一共只需一共只需0.75s,与与1ms比较极比较极短,所以我们在外循环里忽略不短,所以我们在外循环里忽略不计了。外循环的循环初值仍设为计了。外循环的循环初值仍设为1000次次,对应的十六进制为,对应的十六进制为3E8H。2 条件控制循环条件控制循环条条件件控控制制循循环环需需要要利利用用特特定定条条件件判判断循环是否结束断循环是否结束条条件件控控制制循循环环用用条条件件转转移移指指令令判判断断循环条件循环条件转转移移指指令令可可以以指指定定目目的的标标号号来来改改变变程程序序的的运运行行顺顺序序,如如果果目目的的标标号号指指向向一一个个重重复复执执行行的的语语句句体体的
12、的开开始始或或结束,便构成了循环控制结构结束,便构成了循环控制结构补充例:显示以补充例:显示以0结尾的字符串结尾的字符串;数据段;数据段string db Let us have a try!,0;代码段代码段mov bx,offset stringagain:mov dl,bxcmp dl,0jz done;为为0结束结束mov ah,2;不为不为0,显示,显示int 21hinc bx;指向下一个字符指向下一个字符jmp againdone:条件控制循环条件控制循环先判断后循环先判断后循环流程图流程图BXBX赋偏移地址赋偏移地址赋偏移地址赋偏移地址DLDL取字节取字节取字节取字节显示显示显
13、示显示BX+1BX+1是是是是0 0吗?吗?吗?吗?N NY Y结束结束结束结束6.5 子程序子程序 一、子程序指令一、子程序指令子程序是完成特定功能的一段程序子程序是完成特定功能的一段程序当当主主程程序序(调调用用程程序序)需需要要执执行行这这个个功功能能时时,采采用用CALL调调用用指指令令转转移移到到该该子子程程序序的的起起始始处处执行执行当当运运行行完完子子程程序序功功能能后后,采采用用RET返返回回指指令令回到主程序继续执行回到主程序继续执行演示演示 转移指令转移指令有去无回有去无回 子程序子程序调用需要返回调用需要返回,其其中中利利用用堆堆栈栈保保存存返返回回地地址址1.子程序调用
14、指令子程序调用指令CALLCALL指令分成指令分成4种类型(类似种类型(类似JMP)CALL label;段内调用、直接寻址段内调用、直接寻址CALL r16/m16;段内调用、间接寻址段内调用、间接寻址CALL far ptr label;段间调用、直接寻址段间调用、直接寻址CALL far ptr mem;段间调用、间接寻址段间调用、间接寻址CALL指令指令保存返回地址保存返回地址:n段内调用段内调用入栈偏移地址入栈偏移地址IPSPSP2,SS:SPIPn段间调用段间调用入栈偏移地址入栈偏移地址IP和段地址和段地址CSSPSP2,SS:SPCSSPSP2,SS:SPIP2.子程序返回指令子
15、程序返回指令RET根据段内和段间、有无参数,分成根据段内和段间、有无参数,分成4种类型种类型RET;无参数段内返回无参数段内返回RET i16;有参数段内返回有参数段内返回RET;无参数段间返回无参数段间返回RET i16;有参数段间返回有参数段间返回弹出弹出CALL指令压入堆栈的指令压入堆栈的返回地址返回地址n段内返回段内返回出栈偏移地址出栈偏移地址IPIPSS:SP,SPSP2n段间返回段间返回出栈偏移地址出栈偏移地址IP和段地址和段地址CSIPSS:SP,SPSP2CSSS:SP,SPSP2二、子程序设计二、子程序设计 把把功功能能相相对对独独立立的的程程序序段段单单独独编编写写和和调调
16、试试,作作为为一一个个相相对对独独立立的的模模块块供供程程序序使使用用,就就形成形成子程序子程序子子程程序序可可以以实实现现源源程程序序的的模模块块化化,可可简简化化源程序结构,可以提高编程效率源程序结构,可以提高编程效率主主程程序序(调调用用程程序序)需需要要利利用用CALL指指令令调调用子程序(被调用程序)用子程序(被调用程序)子程序需要利用子程序需要利用RET指令返回主程序指令返回主程序1、过程定义和子程序编写、过程定义和子程序编写汇汇编编语语言言中中,子子程程序序要要用用一一对对过过程程伪伪指指令令PROC和和ENDP声明,格式如下声明,格式如下(P162)过程名过程名PROC NEA
17、R|FAR;过程体过程体过程名过程名ENDP可可选选的的参参数数指指定定过过程程的的调调用用属属性性。没没有有指指定定过过程程属性,则采用默认属性属性,则采用默认属性NEARNEAR属属性性(段段内内近近调调用用)的的过过程程只只能能被被相相同同代代码段的其他程序调用码段的其他程序调用FARFAR属属性性(段段间间远远调调用用)的的过过程程可可以以被被相相同同或或不不同代码段的程序调用同代码段的程序调用子程序编写注意事项子程序编写注意事项子程序要利用子程序要利用过程定义伪指令过程定义伪指令声明声明子子程程序序最最后后利利用用RET指指令令返返回回主主程程序序,主主程程序序执执行行CALL指令调
18、用子程序指令调用子程序子子程程序序开开始始应应该该保保护护使使用用到到的的寄寄存存器器内内容容(保保护护现现场)场),子程序返回前相应进行恢复,子程序返回前相应进行恢复(恢复现场)(恢复现场)子子程程序序中中对对堆堆栈栈的的压压入入和和弹弹出出操操作作要要成成对对使使用用,保保持堆栈的平衡持堆栈的平衡子子程程序序应应安安排排在在代代码码段段的的主主程程序序之之外外,最最好好放放在在主主程程序序执执行行终终止止后后的的位位置置(返返回回DOS后后、汇汇编编结结束束END伪伪指指令令前前),也也可可以以放放在在主主程程序序开开始始执执行行之之前前的位置的位置2、子程序编写注意事项(续)、子程序编写
19、注意事项(续)(6)子程序允许)子程序允许嵌套和递归嵌套和递归(7)处处理理好好子子程程序序与与主主程程序序间间的的参参数数传传递递问问题题(8)提提供供必必要要的的子子程程序序说说明明信信息息。每每个个子子程程序序应应有有必必要要的的使使用用注注释释,它它包包括括:子子程程序序名名;功功能能、技技术术指指标标(如如执执行行时时间间等等);占占用用寄寄存存器器和和存存储储单单元元;入入口口、出出口参数;口参数;嵌套哪些子程序等。嵌套哪些子程序等。嵌套嵌套嵌套嵌套递归递归递归递归重入重入重入重入【例【例6.7】延时子程序】延时子程序DELAY1S:PUSHFPUSHBXPUSHCX MOVBX,
20、3E8HLP2:MOVCX,176HLP1:PUSHFPOPFLOOPLP1DECBXJNZLP2POPCXPOPBXPOPFRET6.4节节中中的的延延时时程程序序,在在实实际际应应用用中中一一般般作作为为子子程程序序调调用用,现现在在把把延延时时1s的的程程序序改改成成子子程序。程序。【例【例6.8】找找出出一一个个数数据据块块中中的的最最大大数数。其其中中,数数据据块块的的长长度度1,并并且且放放在在内内存存(2001)单单元元中中,而而数数据据块块本本身身是是从从(2002)单单元元开开始始存存放放的的,最最后后,把把找找出出的的最最大大值值放放到到(2000)单单元元中中。假设这段数
21、据块中的数都是无符号的假设这段数据块中的数都是无符号的8位数。位数。MOVSI,2001H ;指向数据长度的单元指向数据长度的单元MOVCL,SI;取出作为循环次数取出作为循环次数INCSI ;指针指向第一个数指针指向第一个数MOVAL,00;设置最大值设置最大值00MOVCH,00;初始化初始化LP:CLC ;清除进位位清除进位位CMPAL,SI;取出数与最大值比较取出数与最大值比较JCBB ;AL中数小,转到取代处中数小,转到取代处JMPAA;AL中数大,跳过去中数大,跳过去BB:MOVAL,SI;把大数放到把大数放到ALAA:INCSI ;指针下移指针下移LOOPLP ;次数减次数减1,
22、判循环结束否,判循环结束否 MOV2000H,AL ;最大值保存最大值保存 HLTJBJBJNAEJNAE优化程序:双分支改为单分支优化程序:双分支改为单分支MOVSI,2001HMOVCL,SIINCSI ;指针指向第一个数指针指向第一个数MOVAL,00;设置最大值设置最大值00MOVCH,00;初始化初始化LP:CLC ;清除进位位清除进位位CMPAL,SIJCBBJMPAABB:MOVAL,SIAA:INCSI ;指针下移指针下移LOOPLP MOV2000H,AL HLT MOVSI,2001HMOVCL,SIINCSIMOVAL,00MOVCH,00LP:CLC CMPAL,SIJ
23、NBAA ;JCBB ;JMPAABB:MOVAL,SIAA:INCSILOOPLP MOV2000H,AL HLT改为子程序改为子程序把这段程序改为子程序形式,程序清单如下把这段程序改为子程序形式,程序清单如下 MAX:PUSHFPUSHAXPUSHCXPUSHSI上面程序段上面程序段POPSIPOPCXPOPAXPOPFRET3、参数传递、参数传递主程序与子程序间一个主要问题是参数传递主程序与子程序间一个主要问题是参数传递入入口口参参数数(输输入入参参数数):主主程程序序调调用用子子程程序序时时,提提供给子程序的参数供给子程序的参数出出口口参参数数(输输出出参参数数):子子程程序序执执行行
24、结结束束返返回回给给主主程序的参数程序的参数参数的具体内容参数的具体内容传数值:传送数据本身传数值:传送数据本身传地址:传送数据的主存地址传地址:传送数据的主存地址常用的参数传递方法常用的参数传递方法寄存器寄存器内存(共享变量)内存(共享变量)堆栈堆栈(1)用寄存器传递参数用寄存器传递参数最最简简单单和和常常用用的的参参数数传传递递方方法法是是通通过过寄寄存存器器,只只要把参数存于约定的寄存器中就可以了要把参数存于约定的寄存器中就可以了由由于于通通用用寄寄存存器器个个数数有有限限,这这种种方方法法对对少少量量数数据据可以直接传递数值,而对大量数据只能传递地址可以直接传递数值,而对大量数据只能传
25、递地址采采用用寄寄存存器器传传递递参参数数,注注意意带带有有出出口口参参数数的的寄寄存存器器不不能能保保护护和和恢恢复复,带带有有入入口口参参数数的的寄寄存存器器可可以以保护、也可以不保护,但最好能够保持一致保护、也可以不保护,但最好能够保持一致(2)用共享变量传递参数(内存单元)用共享变量传递参数(内存单元)子子程程序序和和主主程程序序使使用用同同一一个个变变量量名名存存取取数数据据就就是是利用利用共享变量(全局变量)共享变量(全局变量)进行参数传递进行参数传递如如果果变变量量定定义义和和使使用用不不在在同同一一个个源源程程序序中中,需需要要利用利用PUBLIC、EXTREN声明声明如如果果
26、主主程程序序还还要要利利用用原原来来的的变变量量值值,则则需需要要保保护护和恢复和恢复利利用用共共享享变变量量传传递递参参数数,子子程程序序的的通通用用性性较较差差,但但特特别别适适合合在在多多个个程程序序段段间间、尤尤其其在在不不同同的的程程序序模块间传递数据模块间传递数据(3)用堆栈传递参数用堆栈传递参数参参数数传传递递还还可可以以通通过过堆堆栈栈这这个个临临时时存存储储区区。主主程程序序将将入入口口参参数数压压入入堆堆栈栈,子子程程序序从从堆堆栈栈中中取取出出参参数数;子子程程序序将将出出口口参参数数压压入入堆堆栈栈,主主程程序序弹弹出出堆堆栈取得它们栈取得它们采采用用堆堆栈栈传传递递参
27、参数数是是程程式式化化的的,它它是是编编译译程程序序处处理理参参数数传传递递、以以及及汇汇编编语语言言与与高高级级语语言言混混合合编编程程时的常规方法时的常规方法4、子程序应用、子程序应用在在实实际际应应用用中中,可可以以把把各各种种功功能能的的程程序序编编成成子子程程序。序。子子程程序序方方式式也也可可以以利利用用到到编编写写大大型型复复杂杂的的程程序序中中去。去。可可以以把把一一个个复复杂杂的的程程序序分分割割成成很很多多独独立立的的,关关联联较少的模块,分别编写成子程序较少的模块,分别编写成子程序 然然后后,用用一一个个主主程程序序(主主要要由由调调用用子子程程序序指指令令构构成成)把它们串联起来。把它们串联起来。这这样样的的程程序序不不但但结结构构清清晰晰,而而且且对对调调试试也也带带来来极大的方便。极大的方便。小节小节6.4循环程序循环程序 循环程序结构循环程序结构 循环控制循环控制 计数控制计数控制 条件控制条件控制 状态控制状态控制6.5子程序子程序 子程序指令:子程序指令:call ret 子程定义:子程定义:proc,endp 注意事项注意事项:保护现场保护现场 参数传递:寄存器参数传递:寄存器 入入口参数口参数 内存(变量)内存(变量)出口参出口参数数 堆栈堆栈
限制150内