汇编语言程序设计第5章基本汇编语言程序设计.ppt
第五章,基本汇编语言程序设计,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,5.1 汇编语言程序的设计步骤,汇编语言程序设计的基本步骤程序的基本结构,5.1 汇编语言程序的设计步骤,一个良好的程序应该满足以下要求:(1)程序要结构化,简明、可读性好,便于调试。(2)执行速度快,程序代码效率高。(3)占用存储空间少。,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,汇编语言程序设计的基本步骤:1.分析题意,确定数据结构和算法2.根据算法绘制程序流程图3.根据流程图编写程序4.调试程序,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,例5.1 在100个字的无符号整数字中找出最大数。,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,1.分析题意,确定数据结构和算法(1)初始化,建立一个数据指针指向数据区的首地址;(2)将第一个数存入寄存器(如AX)中;(3)调整数据指针,使其指向下一个数;(4)将数据指针所指的数与寄存器AX的内容相比较,如果该数较大,则将其存入AX,否则丢掉;(5)重复执行(3)、(4)两步,直至将数组中的数据全部处理完。,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,2.根据算法绘制程序流程图,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,3.根据流程图编写程序,汇编语言程序设计的基本步骤,5.1 汇编语言程序的设计步骤,4.调试程序两个阶段:静态检查上机运行调试,程序的基本结构,5.1 汇编语言程序的设计步骤,1.顺序结构2.分支结构3.循环结构,程序的基本结构,5.1 汇编语言程序的设计步骤,1.顺序结构,程序的基本结构,5.1 汇编语言程序的设计步骤,2.分支结构,程序的基本结构,5.1 汇编语言程序的设计步骤,3.循环结构,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,5.2 顺序结构的程序设计,例5.2 将一字数据从数据段的某个单元传送到另一个单元。,分析:因为8086.8088指令系统不允许在存储器与存储器之间直接传送数据,所以必须借助CPU内部的通用寄存器AX、BX、CX、DX等,先将存储单元中的字数据传送到寄存器,再将其由寄存器传送到存储器的另一个字单元。,5.2 顺序结构的程序设计,5.2 顺序结构的程序设计,例5.3 将键盘输入的小写字母用大写字母显示出来。,分析:本题目涉及三个知识点:(1)输入:在8086.8088指令系统中,字符的输入是由DOS21H中断的01H子功能来实现的,命令序列如下:MOV AH,01HINT 21H其作用是从键盘接收一个字符并将该字符的ASCII码存入寄存器AL中。,5.2 顺序结构的程序设计,(2)输出:在8086.8088指令系统中,字符的输出是由DOS21H中断的02H子功能来实现的,命令序列如下:MOV AH,02HINT 21H其作用是将寄存器DL中所存放的字符进行显示输出,故在执行该命令序列之前,应先将被输出字符的ASCII码存入DL中。,(3)小写字母向大写字母的转换:将小写字母的ASCII码值减去20H即可得到对应大写字母的ASCII码值。,5.2 顺序结构的程序设计,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,5.3 分支结构的程序设计,双分支结构的程序设计多分支程序设计,双分支结构的程序设计,5.3 分支结构的程序设计,框架结构:先行指令JXX 标号1指令序列1JMP 标号2;转到出口标号1:指令序列2标号2:,功能:JXX条件成立时转到标号1处执行指令序列2,否则执行指令序列1,然后跳转到标号2的程序出口处。,双分支结构的程序设计,5.3 分支结构的程序设计,例5.4 比较两个带符号数的大小,把大数存入MAX单元。,分析:比较两数可用CMP指令,而带符号数的比较结果可由标志位SF、OF来确定,选用的转移指令应为JG、JL等。,5.3 分支结构的程序设计,双分支结构的程序设计,5.3 分支结构的程序设计,例5.5 比较两个字符串STRING1和STRING2所含字符是否完全相同,若相同则显示MATCH,若不相同则显示NO MATCH。,分析:比较两个字符串可用指令REPE CMPSB,比较后如果ZF=1,则两个字符串完全相同,如果ZF=0,则两个字符串不完全相同。字符串的输出是由DOS21H中断的09H子功能来实现的,该子功能要求将被输出的字符串存入数据段中,存储时以结束,输出时将其首地址存入DX寄存器。,5.3 分支结构的程序设计,多分支序设计,5.3 分支结构的程序设计,例5.6 比较两个无符号整数A和B,若AB则输出“”,若AB则输出“”,若A=B则输出“=”。,分析:根据题意,本题应有三个分支:AB、AB和A=B,各分支均可用条件转移指令来实现。,5.3 分支结构的程序设计,多分支序设计,5.3 分支结构的程序设计,例5.7 已知两个整数字节变量A和B,试编写完成下列操作的程序:(1)若两个数中只有一个是奇数,则将奇数存入ABUF单元,偶数存入BBUF单元中。(2)若两个数均为奇数,则两数分别加1,并存回原变量处。(3)若两个数均为偶数,则两变量不变。,分析:在计算机中,数据的奇偶性取决于最低位的值,0为偶数,1为奇数。因此可采用位测试的办法来判断。首先判断A与B是否同种类型的数,不是同种类型,再判断B是否为偶数,由B的类型可确定A的类型,再按要求(1)进行处理;同样,当A、B是同种类型时,也判断B是否为偶数,再按要求(2)或(3)进行处理。判断A、B两数是否同类,可使用XOR指令将两数异或,若结果的最低位为0,则两数同类。,多分支程序设计,5.3 分支结构的程序设计,5.3 分支结构的程序设计,DATA SEGMENTABUF DB ABBUF DB BDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AXMOV AL,ABUFMOV BL,BBUFXOR AL,BLTEST AL,01H;测试是否同类JZ CLASS;是同类,转CLASSTEST BL,01H;不是同类,测试B是否偶数JZ EXIT;B是偶数,满足要求(1),转EXITXCHG BL,ABUF;B不是偶数,按要求(1),交换两数MOV BBUF,BLJMP EXIT;转EXITCLASS:TEST BL,01H;同类时,测试B是否偶数JZ EXIT;B是偶数,满足要求(3),转EXITINC ABUF;B不是偶数,按要求(2),两数同时加1INC BBUFEXIT:MOV AH,4CHINT 21HCODE ENDSEND START,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,5.4 循环结构的程序设计,循环程序的结构循环结构的程序设计方法,循环程序的结构,5.4 循环结构的程序设计,循环程序都可由如下三部分组成:1.设置循环的初始状态2.循环体3.循环控制部分,循环程序的结构,5.4 循环结构的程序设计,1.设置循环的初始状态循环程序的初始状态,应该在进入循环体之前设置,其目的是保证循环体能够正常运行和结束,具体内容包括设置循环次数的计数值或其他能使循环结束的条件的初值,以及为循环体正常工作而建立的初始状态等。,循环程序的结构,5.4 循环结构的程序设计,2.循环体循环体是整个循环程序中需要重复执行的程序段,即循环工作的主体。它由循环的工作部分和修改部分组成。循环的工作部分是为完成程序功能而设计的主要程序段,循环的修改部分则是为保证循环体在执行有限次后能够正常结束而设置的程序段,一般是对循环控制参数进行修改,而该参数的变化通常是有规律的。,循环程序的结构,5.4 循环结构的程序设计,3.循环控制部分每个循环程序必须选择一个循环控制条件来控制循环的运行和结束,而合理地选择这个控制条件就成为循环程序设计的关键问题。,循环程序的结构,5.4 循环结构的程序设计,(1)循环次数已知,用循环次数作为循环的控制条件MOV CX,N标号:LOOP 标号,循环程序的结构,5.4 循环结构的程序设计,(2)循环次数已知,但也有可能使用其他特征或条件来使循环提前结束MOV CX,N标号:LOOPZ.LOOPNZ 标号,循环程序的结构,5.4 循环结构的程序设计,(3)循环次数是未知的,这时就要根据具体情况找出控制循环结束的条件直到型循环:标号:影响条件标志位的指令JXX 标号,循环程序的结构,5.4 循环结构的程序设计,当型循环:标号2:影响条件标志位的指令JXX 标号1JMP 标号2标号1:,循环程序的结构,5.4 循环结构的程序设计,设计循环程序的步骤:(1)分析问题,确定循环次数是已知的还是未知的,是否有提前结束循环的情况,从而决定选用哪一种循环最恰当;(2)根据循环变化的规律,确定适合于循环设计的工作部分;(3)考虑循环参数的修改部分,分析并确定参数的每次修改方法;(4)设置循环控制部分及循环参数的置初值部分,可根据循环程序控制方法的不同,来设置循环参数的初值。,循环结构的程序设计方法,5.4 循环结构的程序设计,两种基本模式:单循环结构多重循环结构,循环结构的程序设计方法,5.4 循环结构的程序设计,1.单循环结构2.多重循环结构,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,例5.8 编程计算10个整数之和(不考虑溢出),并将结果存入SUM中。,分析:这10个整数可存放在数组ARRAY中,从而将题目转化为对数组元素求和,根据数组元素下标的变化规律来设计循环,本题中循环次数固定为10次,因此可使用LOOP指令。,5.4 循环结构的程序设计,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,例5.9 在ADDR单元中存放着数Y的地址,试编制一程序把Y中1的个数存入COUNT单元中。,分析:要测出Y中1的个数就应逐位测试,一个比较简单的办法是用移位的方法把各位依次移到最高位,然后根据最高有效位是否为1来计数。循环的结束可以用计数值16来控制,但考虑到数Y的末几位全为0(如1011010000000000B)的特殊情况,循环应能提前结束,且可能为零次循环,为了提高程序的执行效率,应采用当型结构,以测试数是否为0来作为结束条件。,5.4 循环结构的程序设计,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,例5.10 有一串20个字符的字符串存储于首地址为STRING的存储区中,要求在字符串中查找空格(ASCII码为20H),如果找到则输出“FOUND SPACE”,否则输出“NOT FOUND SPACE”。,分析:本题可以使用查找字符串的指令REPNZ SCASB来实现,也可以用循环指令来实现。在此,我们采用循环指令的方法用CMP指令逐个字符进行查找。根据题意,有两种可能性:(1)在查找中找到了空格符,此时ZF=1,应该提前结束循环;(2)如一直查找到字符串结束还未找到空格符,则由于循环计数器CX变为0而结束循环。据此,本题应考虑使用LOOPE或LOOPNE指令。,5.4 循环结构的程序设计,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,例5.11 将正数N插入一个已排序的字数组的正确位置。该数组的首地址和末地址分别为ARRAY HEAD和AYYAY END,其中所有数均为正数且已按递增的次序排列。,分析:由于数组的首地址和末地址都是已知的,因此数组长度可以确定。但是这里只要求插入一个数,并不一定要扫描整个数组,所以可以用找到应插入数的位置作为循环的结束条件。此外,为空出要插入数的位置,其后的全部元素都应后移一个字(即向地址增大的方向移动一个字),所以算法上应该从数组的尾部向头部查找,可逐字取出数组中的一个数K与N作比较,如KN,则把K后移一个字,然后继续向前查找;如果KN,则把N插入在K之后就可以结束程序了。,5.4 循环结构的程序设计,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,例5.12 设有数组X和Y。X数组中有X1,X2,X10;Y数组中有Y1,Y2,Y10。试编制程序计算:Z1=X1+Y1Z2=X2+Y2Z3=X3-Y3Z4=X4-Y4Z5=X5-Y5Z6=X6+Y6Z7=X7-Y7Z8=X8-Y8Z9=X9+Y9Z10=X10+Y10结果存入Z数组。,循环结构的程序设计方法单循环结构,5.4 循环结构的程序设计,分析:对于这种问题,我们也可用循环程序结构来完成。已知循环计数值为10,每次循环的操作数是可以顺序取出的,但所做的操作却有不同,这里有两种操作:加法和减法。为了区别每次应该做哪一种操作,可以设立标志位,如标志位为0做加法,为1做减法,这样进入循环后只要判别标志位就可确定应该做的操作了。,5.4 循环结构的程序设计,循环结构的程序设计方法多重循环结构,5.4 循环结构的程序设计,多重循环指的是循环的嵌套,即循环体部分又包含了另一个循环。多重循环程序设计的基本方法和单循环的设计方法是一致的,应分别考虑各层循环的控制条件及其程序实现,相互之间不能混淆。另外应该注意在每次通过外层循环再次进入内层循环时,内层循环的初始条件必须重新设置。特别要注意的是,如果内、外层循环都使用CX做循环计数器,在进入内层循环之前一定要先把外层循环的循环计数器的值保存下来,才能设置内层循环的次数。,循环结构的程序设计方法多重循环结构,5.4 循环结构的程序设计,常见的双重循环的程序结构:外层循环初始化MOV CX,外层循环次数M LOOP1:;外层循环体的指令MOV DI,CX;保存外层循环次数 内层循环初始化MOV CX,内层循环次数N;设置内层循环次数LOOP2:;内层循环的循环体LOOP LOOP2;继续内层循环MOV CX,DI;恢复外层循环的次数;外层循环体的指令序列 LOOP LOOP1;继续外层循环,第5章基本汇编语言程序设计,5.1 汇编语言程序的设计步骤5.2 顺序结构的程序设计5.3 分支结构的程序设计5.4 循环结构的程序设计5.5 子程序设计,5.5 子程序设计,子程序的定义子程序的设计要求子程序的参数传递及应用举例,子程序的定义,5.5 子程序设计,过程名 PROC 属性 过程名 ENDP,过程名为标识符,其写法与标号的写法相同,它代表子程序入口的符号地址;属性是指子程序的类型属性,它可以是NEAR或FAR。,属性的确定原则如下:如果子程序只允许被与它在同一代码段中的程序调用,则属性应设置为NEAR,否则,应设置为FAR。,子程序的定义,5.5 子程序设计,例5.13 调用程序和子程序在同一代码段中。CODE SEGMENT;主程序MAIN PROC FAR CALL SUB1RETMAIN ENDP;子程序SUB1 PROC NEARRETSUB1 ENDPCODE ENDS,由于调用程序MAIN和子程序SUB1在同一代码段中,所以SUB1定义为NEAR属性,这样MAIN中对SUB1的调用和SUB1中的RET就都是NEAR属性的。但是一般说来,主过程MAIN应定义为FAR属性,这是由于我们把程序的主过程看做是DOS调用的一个子程序,因而DOS对MAIN的调用以及MAIN中的RET就是FAR属性的。,子程序的定义,5.5 子程序设计,例5.14 调用程序和子程序不在同一个代码段内。;代码段1CODE1 SEGMENT;子程序SUBT PROC FARRETSUBT ENDPCALL SUBT;段内调用CODE1 ENDS;代码段1结束;代码段2CODE2 SEGMENT CALL SUBT;段间调用CODE2 ENDS;代码段2结束,子程序的设计要求,5.5 子程序设计,一个完整的子程序必须包括以下几个方面的内容。1.子程序的说明文件2.子程序的现场保护和现场恢复3.子程序的调用和返回,子程序的设计要求,5.5 子程序设计,1.子程序的说明文件为了使子程序有较强的通用性和便于用户调用,在设计子程序的同时,还要建立相应的文档说明,使用户能够了解该子程序的功能和调用方法。说明文件一般应包含子程序名、子程序的功能、子程序对寄存器及存储单元的使用情况、子程序的输入输出参数等,还可以加入一个示例来帮助用户了解该子程序的功能。,子程序的设计要求,5.5 子程序设计,2.子程序的现场保护和现场恢复汇编语言所处理的对象主要是CPU的寄存器,而CPU寄存器的数量是有限的,再加上调用程序和子程序又经常是分别编制的,所以它们所使用的寄存器往往会发生冲突,即调用程序和子程序可能用到同一个寄存器而使其信息相互覆盖,导致信息丢失。为了避免这种错误的产生,在进入子程序后,应首先把子程序中所要使用的寄存器的原有内容保存在堆栈中,这种操作称为“现场保护”,在退出子程序之前再把这些寄存器恢复为原有内容,这种操作称为“现场恢复”。,子程序的设计要求,5.5 子程序设计,3.子程序的调用和返回 子程序的调用和返回是由设在主程序中的CALL指令和设在子程序末尾的RET指令来完成的。为了保证其正确性,除PROC的属性要正确选择外,还应该注意子程序运行期间的堆栈状态。,子程序的参数传递及应用举例,5.5 子程序设计,主程序在调用子程序之前,必须把本次操作中要加工处理的数据传递给子程序,这些数据称为输入参数。当子程序执行完毕返回主程序时,应该把本次操作的最终结果传递给主程序,这些结果称为输出参数。在主程序和子程序之间的这种信息传送就称为参数传递(或称变量传送或过程通信)。,子程序的参数传递及应用举例,5.5 子程序设计,常用的参数传递方式主要有三种:1.用寄存器传递参数2.用堆栈传递参数3.用地址表传递参数,子程序的参数传递及应用举例,5.5 子程序设计,1.用寄存器传递参数这种方法是将子程序的输入参数由主程序放入规定的寄存器中带入子程序。执行子程序的结果也放入规定的寄存器中带回主程序。采用这种方法设计子程序时,主、子程序必须按约定在指定的寄存器中取出或存入指定参数。Register_transfer.s,子程序的参数传递及应用举例,5.5 子程序设计,2.用堆栈传递参数用堆栈传递参数的方法是在调用子程序之前,用PUSH指令将输入参数压入堆栈,在子程序中设法依次获得这些参数。并对这些参数进行加工处理,再将处理结果压入堆栈,返回主程序后,再通过出栈获得结果,也可以在子程序中将结果直接送入存储单元。使用这种方式传递参数时,要特别注意堆栈中断点的保存与恢复。Stack_transfer.s,子程序的参数传递及应用举例,5.5 子程序设计,3.用地址表传递参数这种方法是在主程序中建立一个地址表,把要传送给子程序的参数都存放在地址表中,然后把地址表的首地址通过寄存器传送到子程序中去。子程序通过地址表取得所需参数,并把结果存入指定的存储单元。Address_transfer.s,