程序设计的基本方法.ppt
第四章 程序设计的基本方法 顺序、分支、循环程序和子程序的设计是汇编语言程序设计的基本内容。在此基础上还要掌握汇编语言程序设计的基本方法和技巧,包括递归子程序设计、多模块程序设计方法等。4.1 概述程序设计通常从两个方面入手,一是要认真分析问题的要求,选择好的解决方法;二是要针对选定的算法,编写高质量的程序。高质量的程序在满足设计要求、实现预定功能的基础上,还应尽可能实现以下几点:1)结构清晰、简明、易读、易调试;2)执行速度快;3)占用存储空间少。多读、多写、多上机调试各种程序!多读、多写、多上机调试各种程序!多读、多写、多上机调试各种程序!多读、多写、多上机调试各种程序!一、汇编语言程序设计的一般步骤:分析问题,合适的解题方法;根据具体问题,确定输入输出数据的格式;分配存储区并给变量命名(包括分配寄存器);绘制程序流程图;根据流程图编写程序;静态检查、上机调试。二、程序流程图常用符号4.2 顺序程序设计顺序程序设计 例1 从键盘输入0至9中任一自然数x,求其立方值。分析:可以用乘法运算,也可以用查表实现。输入数据:1位自然数,用一字节单元存放;输出数据最大为729,用一个字单元存放。存储单元分配:字节变量X存放输入的自然数;字变量XXX存放X的立方值;立方表首址为TAB,表中共10项,每项占一个字。X与其立方值的对应关系:(TAB+2*X)=X的立方值绘制流程图。编写程序。4.3 分支程序设计分支程序设计 在分支程序中,不同的条件往往是通过标志寄存器中条件标志的不同状态反映的。而程序的分支通过转移指令来实现,因此分支程序设计中一个重要问题是根据各标志的不同状态选用合适的转移指令。4.3.1 转移指令 转移指令共计19条,分为两类无条件转移指、条件转移指令(不影响任何标志位)一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)基本格式为:J 标号(代表一种转移条件)条件转移指令根据检测标志位的状态来判断条件,若条件为真,则转至标号处执行程序,否则顺序往下执行程序。操作:(IP)(IP)+D(8位偏移量,-128127)条件转移指令 分三类:(1)简单条件转移指令(10条,见P92 表4.1)根据单个标志的状态决定是否转移(2)无符号数条件转移指令(4条)用于检测无符号数的比较(3)有符号数条件转移指令(4条)用于检测带符号数的比较 4.3.1 4.3.1 转移指令转移指令转移指令转移指令 一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)1.简单条件转移指令 在在在在IBM PCIBM PCIBM PCIBM PC中,标志中,标志中,标志中,标志CFCFCFCF、ZFZFZFZF、SFSFSFSF、OFOFOFOF、PFPFPFPF分别为分别为分别为分别为0 0 0 0或或或或1 1 1 1,可以表示,可以表示,可以表示,可以表示10101010种状态,因而设置了种状态,因而设置了种状态,因而设置了种状态,因而设置了10101010条简单条件转换指条简单条件转换指条简单条件转换指条简单条件转换指令。令。令。令。JE/JZJNE/JNZJSJNSJOJNOJCJNCJP/JPEJNP/JPO 先执行影响标志位的指令(如算术运算、比较及位测试等指令),再执行适当的条件转移指令检测相应的标志位,根据条件实现转移。例:下列程序中X、Y均为字变量,X中存放着有符号数x.MOV Y,-1MOV AX,XCMP AX,0JEEXIT1ADD AX,1000HJOOVERFLOWJNSEXIT1NEG AXEXIT1MOV Y,AXMOV AH,4CHINT21HOVERFLOW:MOV AH,4CHINT21H一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)2.无符号数条件转移指令 该类指令往往跟在比较指令之后,视比较对象为无该类指令往往跟在比较指令之后,视比较对象为无该类指令往往跟在比较指令之后,视比较对象为无该类指令往往跟在比较指令之后,视比较对象为无符号数,设置了高于、高于或等于、低于、低于或等于符号数,设置了高于、高于或等于、低于、低于或等于符号数,设置了高于、高于或等于、低于、低于或等于符号数,设置了高于、高于或等于、低于、低于或等于4 4 4 4条指令。条指令。条指令。条指令。1 1 1 1)JA/JNBEJA/JNBEJA/JNBEJA/JNBE:当当当当CF=0CF=0CF=0CF=0且且且且ZF=0ZF=0ZF=0ZF=0时转移。时转移。时转移。时转移。2 2 2 2)JAE/JNBJAE/JNBJAE/JNBJAE/JNB:当当当当CF=0CF=0CF=0CF=0或或或或ZF=1ZF=1ZF=1ZF=1时转移。时转移。时转移。时转移。3 3 3 3)JB/JNAEJB/JNAEJB/JNAEJB/JNAE:当当当当CF=1CF=1CF=1CF=1且且且且ZF=0ZF=0ZF=0ZF=0时转移。时转移。时转移。时转移。4 4 4 4)JBE/JNAJBE/JNAJBE/JNAJBE/JNA:当当当当CF=1CF=1CF=1CF=1或或或或ZF=1ZF=1ZF=1ZF=1时转移。时转移。时转移。时转移。一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)3.有符号数条件转移指令 该类指令往往跟在比较指令之后,视比较对象为有该类指令往往跟在比较指令之后,视比较对象为有该类指令往往跟在比较指令之后,视比较对象为有该类指令往往跟在比较指令之后,视比较对象为有符号数,设置了大于、大于或等于、小于、小于或等于符号数,设置了大于、大于或等于、小于、小于或等于符号数,设置了大于、大于或等于、小于、小于或等于符号数,设置了大于、大于或等于、小于、小于或等于4 4 4 4条指令。条指令。条指令。条指令。1 1 1 1)JG/JNLEJG/JNLEJG/JNLEJG/JNLE:当当当当SF=OFSF=OFSF=OFSF=OF且且且且ZF=0ZF=0ZF=0ZF=0时转移。时转移。时转移。时转移。2 2 2 2)JGE/JNLJGE/JNLJGE/JNLJGE/JNL:当当当当SF=OFSF=OFSF=OFSF=OF或或或或ZF=1ZF=1ZF=1ZF=1时转移。时转移。时转移。时转移。3 3 3 3)JL/JNGEJL/JNGEJL/JNGEJL/JNGE:当当当当SFSFSFSF不等于不等于不等于不等于OFOFOFOF且且且且ZF=0ZF=0ZF=0ZF=0时转移。时转移。时转移。时转移。4 4 4 4)JLE/JNGJLE/JNGJLE/JNGJLE/JNG:当当当当SFSFSFSF不等于不等于不等于不等于OFOFOFOF或或或或ZF=1ZF=1ZF=1ZF=1时转移。时转移。时转移。时转移。一、一、一、一、条件转移指令条件转移指令条件转移指令条件转移指令 (1818条)条)条)条)例1:MOVAL,-40HCMPAL,50HJGL1;比较JAL1例例例例2 2 2 2:分析下述代码的功能分析下述代码的功能分析下述代码的功能分析下述代码的功能MOVSI,0L:MOV WORD PRT SI,0ADDSI,2CMPSI,OF000HJBEL 无条件转移指令不构成分支程序,但在分支程序中经常使用它将各分支的出口汇集到一起,特别是当条件转移指令的转移范围超过-128127个字节时,往往要借助无条件转移指令实现。例:JLL1.L1二、无二、无二、无二、无条件转移指令条件转移指令条件转移指令条件转移指令JGEL0JMPL1L0:.L1:无条件转移指令分为段内直接转移、段内间接转移、段间直接转移、段间间接转移。例:直接转移:JMPNEXT间接转移:JMPWORD PTR BXJMPDWORD PTR BX二、无二、无二、无二、无条件转移指令条件转移指令条件转移指令条件转移指令分析问题,合适的解题方法;根据具体问题,确定输入输出数据的格式;分配存储区并给变量命名(包括分配寄存器);绘制程序流程图;根据流程图编写程序;静态检查、上机调试。4.3.2 4.3.2 分支程序设计举例分支程序设计举例分支程序设计举例分支程序设计举例 4.3.2 4.3.2 分支程序设计举例分支程序设计举例分支程序设计举例分支程序设计举例 例例1 编写计算下面函数值的程序(编写计算下面函数值的程序(x,y的值均在的值均在-128127之间)之间)输入数据为输入数据为x,y,输出数据为,输出数据为a 4.3.2 4.3.2 分支程序设计举例分支程序设计举例分支程序设计举例分支程序设计举例 例例2 从键盘输入从键盘输入09中任一自然数中任一自然数x,求其立方值。若输入的字,求其立方值。若输入的字符不是符不是09中的某数字,显示中的某数字,显示“INPUT ERROR!”,表明输,表明输入错误。入错误。4.3.2 4.3.2 分支程序设计举例分支程序设计举例分支程序设计举例分支程序设计举例 选择合适的分支指令;选择合适的分支指令;要为每个分支安排出口;要为每个分支安排出口;应把各分支中的公共部分尽量提到分支前或分支后的公应把各分支中的公共部分尽量提到分支前或分支后的公共程序段中,使程序简短、清晰;共程序段中,使程序简短、清晰;在分支比较多时,流程图中对每个分支判断的先后次序在分支比较多时,流程图中对每个分支判断的先后次序应尽量与问题提出的先后次序一致。程序也要与流程图应尽量与问题提出的先后次序一致。程序也要与流程图中各分支的先后次序一致;中各分支的先后次序一致;在调试分支程序时,要假定各种可能的输入数据,沿着在调试分支程序时,要假定各种可能的输入数据,沿着每一支路逐一检查,测试程序是否正确。每一支路逐一检查,测试程序是否正确。分支程序设计中的注意事项:分支程序设计中的注意事项:4.4 循环程序设计循环程序设计 在实际问题处理程序中,常常需要按照一定规在实际问题处理程序中,常常需要按照一定规在实际问题处理程序中,常常需要按照一定规在实际问题处理程序中,常常需要按照一定规律,多次重复执行一串语句,这类程序叫做循环程律,多次重复执行一串语句,这类程序叫做循环程律,多次重复执行一串语句,这类程序叫做循环程律,多次重复执行一串语句,这类程序叫做循环程序序序序 。本节主要内容:本节主要内容:本节主要内容:本节主要内容:循环程序的结构和控制方法;循环程序的结构和控制方法;循环程序的结构和控制方法;循环程序的结构和控制方法;单重循环程序的设计;单重循环程序的设计;单重循环程序的设计;单重循环程序的设计;多重循环程序的设计。多重循环程序的设计。多重循环程序的设计。多重循环程序的设计。4.4.1 循环程序的结构循环程序的结构 4.4.1 循环程序的结构循环程序的结构 例例例例1 1 已知有已知有已知有已知有n n个元素存放在以个元素存放在以个元素存放在以个元素存放在以BUFBUF为首址的字节存储区中,为首址的字节存储区中,为首址的字节存储区中,为首址的字节存储区中,试统计其中负元素的个数。试统计其中负元素的个数。试统计其中负元素的个数。试统计其中负元素的个数。存储单元及寄存器分配:存储单元及寄存器分配:存储单元及寄存器分配:存储单元及寄存器分配:BXBX:BUFBUF存储区地址指针;存储区地址指针;存储区地址指针;存储区地址指针;CXCX:循环计数器(初值为元素个数:循环计数器(初值为元素个数:循环计数器(初值为元素个数:循环计数器(初值为元素个数n n)AXAX:记录负元素的个数;:记录负元素的个数;:记录负元素的个数;:记录负元素的个数;字变量字变量字变量字变量R R:存放负元素的个数。:存放负元素的个数。:存放负元素的个数。:存放负元素的个数。保证循环正常执行和结束的条件:正确地初始化循环控制计数和初始条件 正确地检测循环条件 必须保证能达到循环结束条件(例如在循环体内有修改循环控制值的指令)4.4.2 循环控制方法循环控制方法 一、一、一、一、计数控制计数控制计数控制计数控制当循环次数已知时,通常使用计数控制法,常用当循环次数已知时,通常使用计数控制法,常用当循环次数已知时,通常使用计数控制法,常用当循环次数已知时,通常使用计数控制法,常用以下三种方式实现:以下三种方式实现:以下三种方式实现:以下三种方式实现:循环次数循环次数循环次数循环次数n n送入循环计数器,每循环一次计数器送入循环计数器,每循环一次计数器送入循环计数器,每循环一次计数器送入循环计数器,每循环一次计数器减减减减1 1,直至计数器为,直至计数器为,直至计数器为,直至计数器为0 0时结束;时结束;时结束;时结束;循环次数的负值送入循环计数器,每循环一次计循环次数的负值送入循环计数器,每循环一次计循环次数的负值送入循环计数器,每循环一次计循环次数的负值送入循环计数器,每循环一次计数器加数器加数器加数器加1 1,直至计数器为,直至计数器为,直至计数器为,直至计数器为0 0时结束;时结束;时结束;时结束;先将先将先将先将0 0送循环计数器,每循环一次计数器加送循环计数器,每循环一次计数器加送循环计数器,每循环一次计数器加送循环计数器,每循环一次计数器加1 1,直,直,直,直至计数器的内容与循环次数至计数器的内容与循环次数至计数器的内容与循环次数至计数器的内容与循环次数n n相等时结束。相等时结束。相等时结束。相等时结束。4.4.2 循环控制方法循环控制方法 二、二、二、二、条件控制条件控制条件控制条件控制当循环次数无法事先确定,但它与问题中的某些条件当循环次数无法事先确定,但它与问题中的某些条件当循环次数无法事先确定,但它与问题中的某些条件当循环次数无法事先确定,但它与问题中的某些条件有关,这些条件可以通过指令来测试,若测试结果满足循环有关,这些条件可以通过指令来测试,若测试结果满足循环有关,这些条件可以通过指令来测试,若测试结果满足循环有关,这些条件可以通过指令来测试,若测试结果满足循环条件,则继续循环,否则结束循环。条件,则继续循环,否则结束循环。条件,则继续循环,否则结束循环。条件,则继续循环,否则结束循环。MOV CL,0L:AND AX,AXJZ EXITSAL AX,1JNC LINC CLJMP LEXIT:MOV CL,0MOV BX,16L:SAL AX,1JNC NEXTINC CLNEXT:DEC BXJNZ L4.4.2 循环控制方法循环控制方法 循环控制指令 循环控制指令的转移范围为:-128+127字节(2)等于继续循环指令 格式:LOOPZ/LOOPE 标号 格式:LOOP 标号 操作:如图所示(1)LOOP指令(CX)0?执行循环体(CX)(CX)-1是否退出循环(CX)0 且 ZF=1?(CX)0 且 ZF=0?(3)不等于继续循环指令格式:LOOPNZ/LOOPNE 标号 MOV CX,80 MOV SI,-1 MOV AL,$AGAIN:INC SI CMP AL,STRSSI LOOPNE AGAIN MOV LEN,SI设:STRS DB string$例例例例:求求求求存放在存放在存放在存放在STRSSTRS存储区中的存储区中的存储区中的存储区中的字符串长度。字符串长度。字符串长度。字符串长度。4.4.2 循环控制方法循环控制方法 4.4.3 单重循环程序设计单重循环程序设计 循环体内不再包含循环结构的程序。循环体内不再包含循环结构的程序。循环体内不再包含循环结构的程序。循环体内不再包含循环结构的程序。一、循环次数已知的循环程序设计一、循环次数已知的循环程序设计例例1 已知以已知以BUF为首址的字存储区中存放着为首址的字存储区中存放着n个个有符号二进制数,试编写程序,将其中大于等于有符号二进制数,试编写程序,将其中大于等于0的数依次送入的数依次送入BUF1为首址的字存储区中,小于为首址的字存储区中,小于0的数依次送入以的数依次送入以BUF2为首址的字存储区中。为首址的字存储区中。4.4.3 单重循环程序设计单重循环程序设计 一、循环次数已知的循环程序设计一、循环次数已知的循环程序设计例例2 顺序查表程序顺序查表程序 设有n个登记项存放在以TAB为首址的字节存储区中。每个登记项占4个字节(主目占1个字节,信息占3个字节)。在字节变量A中存有一主目。现需要在表中查找与A中主目相同的登记项。若查到,则把该登记项主目的地址送入DI,信息部分依次送入DH、DL、CH 3个8位寄存器中,且将字节变量F置1。若未查到,将F清0。4.4.3 单重循环程序设计单重循环程序设计 二、最大循环次数未知的循环程序设计二、最大循环次数未知的循环程序设计例例3 已知在以BUF为首地址的字节存储区,存放着以$作结束标志的字符串。试编写程序,在CRT上显示该字符串,并要求将小写字母以大写字母形式显示。二、最大循环次数未知的循环程序设计二、最大循环次数未知的循环程序设计例例4 已知在以PROG为首地址的字节存储区中存放着一段汇编源程序,最后以Ctrl-Z(其ASCII码为1AH)作为结束标志。试编写程序,统计MOV的出现次数,并将结果送入字变量NUM中。4.4.3 单重循环程序设计单重循环程序设计 4.4.3 单重循环程序设计单重循环程序设计 二、最大循环次数未知的循环程序设计二、最大循环次数未知的循环程序设计例例5 已知若干个非0整数存放在以A为首址的字存储区中,末尾以0作为结束标志。现要求将其中的负数删除,而把留下的正数仍连续地重新存储在以A为首址的字存储区中,并把结束标志改为-1,试编写其程序。4.4.3 单重循环程序设计单重循环程序设计 二、最大循环次数未知的循环程序设计二、最大循环次数未知的循环程序设计练习练习 试编制一个程序,产生n个斐波纳契数数列。该数列的第1、2个数分别为0、1,从第3个数开始,每一个数等于前两个数之和。提示提示 存储空间分配:NUM DW 20H FIBONADW50H DUP(0)寄存器:AX、BX中存放数列中连续两个元素,CX为计数器,DI为存储数列元素的指针。4.4.4 多重循环程序设计多重循环程序设计 多重循环即循环体内再套有循环多重循环即循环体内再套有循环。设计多重循环程序时,可以从外层循环到内层循环一层层进行。在设计外层循环时将内层循环看成一个处理粗框,然后再将粗框细化,分成置初值、工作、修改和控制四个部分。例例1 已知mn矩阵A的元素aij按行序存放在以BUFA为首址的字节存储区中,试编写程序,示每行元素的和Si。其中aij 为8位二进制数。4.4.4 多重循环程序设计多重循环程序设计 例例2 在以BUF为首址的字节存储区中存放有n个无符号数x1,x2,xn,现需将它们按从小到大的顺序排列在BUF存储区中,试编写程序。4.4.4 多重循环程序设计多重循环程序设计 4.5 4.5 子程序设计子程序设计 在一个程序中,当不同的地方需要多次使用在一个程序中,当不同的地方需要多次使用在一个程序中,当不同的地方需要多次使用在一个程序中,当不同的地方需要多次使用的某程序段常常单独编制一指令序列。在程序运行的某程序段常常单独编制一指令序列。在程序运行的某程序段常常单独编制一指令序列。在程序运行的某程序段常常单独编制一指令序列。在程序运行时,若需要完成社个给定功能,就转移到这个指令时,若需要完成社个给定功能,就转移到这个指令时,若需要完成社个给定功能,就转移到这个指令时,若需要完成社个给定功能,就转移到这个指令序列,待指令序列执行完后,又返回到原来位置继序列,待指令序列执行完后,又返回到原来位置继序列,待指令序列执行完后,又返回到原来位置继序列,待指令序列执行完后,又返回到原来位置继续执行。这个单独的指令序列就是子程序。续执行。这个单独的指令序列就是子程序。续执行。这个单独的指令序列就是子程序。续执行。这个单独的指令序列就是子程序。本节主要内容:本节主要内容:本节主要内容:本节主要内容:子程序的调用与返回(指令);子程序的调用与返回(指令);子程序的调用与返回(指令);子程序的调用与返回(指令);子程序的定义格式及现场保护方法;子程序的定义格式及现场保护方法;子程序的定义格式及现场保护方法;子程序的定义格式及现场保护方法;主程序与子程序之间传递参数的方式;主程序与子程序之间传递参数的方式;主程序与子程序之间传递参数的方式;主程序与子程序之间传递参数的方式;子程序及其调用举例。子程序及其调用举例。子程序及其调用举例。子程序及其调用举例。子程序设计时要考虑的主要问题:子程序设计时要考虑的主要问题:子程序的调用和返回;子程序的调用和返回;子程序的定义;子程序的定义;主程序和子程序间的参数传递;主程序和子程序间的参数传递;如何编制子程序。如何编制子程序。4.5.1 子程序的概念子程序的概念 一、子程序调用指令一、子程序调用指令CALLCALL:1 1)段内直接调用)段内直接调用格式:格式:CALL CALL 过程名过程名功能:功能:(IPIP)入栈)入栈目的地址目的地址EAIPEAIP2 2)段间直接调用)段间直接调用格式:格式:CALL FAR PTR CALL FAR PTR 过程名过程名功能:功能:(CSCS)入栈,目的地址段首址)入栈,目的地址段首址CS (IPIP)入栈,目的地址)入栈,目的地址EAIPEAIP4.5.2 4.5.2 子程序的调用与返回子程序的调用与返回 一、子程序调用指令一、子程序调用指令CALLCALL:3 3)段内间接调用)段内间接调用格式:格式:CALL WORD PTR OPDCALL WORD PTR OPD功能:功能:(IPIP)入栈)入栈(OPDOPD)IPIP3 3)段间间接调用)段间间接调用格式:格式:CALL DWORD PTR OPDCALL DWORD PTR OPD功能:功能:(CSCS)入栈,()入栈,(OPD+2OPD+2)CS (IPIP)入栈,()入栈,(OPDOPD)IPIP4.5.2 4.5.2 子程序的调用与返回子程序的调用与返回 二、返回指令二、返回指令RETRET:1 1)格式)格式1 1 格式:格式:RETRET功能:功能:(SPSP)IPIP(SPSP)CSCS*段内返回只执行段内返回只执行2 2)格式)格式2 2格式:格式:RET nRET n其中其中n n是偶数,该指令用来废除栈顶是偶数,该指令用来废除栈顶n/2n/2个无用的参数,即个无用的参数,即执行格式执行格式1 1中的步骤后再执行(中的步骤后再执行(SPSP)+nSP+nSP。4.5.2 4.5.2 子程序的调用与返回子程序的调用与返回 一、子程序的定义格式:一、子程序的定义格式:1 1)格式)格式1 1 子程序名子程序名 PROC NEAR PROC NEAR (NEARNEAR可省略)可省略)子程序名子程序名 ENDP ENDP2 2)格式)格式2 2子程序名子程序名 PROC FAR PROC FAR 子程序名子程序名 ENDP ENDP4.5.3 4.5.3 子程序的定义格式及现场保护方法子程序的定义格式及现场保护方法 二、现场的保护与恢复:二、现场的保护与恢复:如果在子程序中用到某些寄存器(或存储单元),如果在子程序中用到某些寄存器(或存储单元),就会破坏这些寄存器(或存储单元)在转子前原有的内就会破坏这些寄存器(或存储单元)在转子前原有的内容,因此必须考虑现场的保护与恢复,一般情况下,在容,因此必须考虑现场的保护与恢复,一般情况下,在子程序的开始安排一串保护现场的语句,在子程序返回子程序的开始安排一串保护现场的语句,在子程序返回指令之前再恢复现场。指令之前再恢复现场。例:例:A PROCA PROCPUSH AXPUSH AXPUSH BXPUSH BXPOP BXPOP BXPOP AXPOP AXRETRETA ENDPA ENDP4.5.3 4.5.3 子程序的定义格式及现场保护方法子程序的定义格式及现场保护方法 一、寄存器法;一、寄存器法;二、约定单元法;二、约定单元法;三、堆栈法。三、堆栈法。4.5.4 4.5.4 主程序与子程序间传递参数的方式主程序与子程序间传递参数的方式 例例1 1:编写将编写将n n个个8 8位无符号二进制数排成递增序位无符号二进制数排成递增序列的子程序列的子程序SORTSORT。4.5.5 4.5.5 子程序及其调用举例子程序及其调用举例 认真复习,融会贯通