您好,欢迎来电子发烧友网! ,新用户?[免费注册]

当前位置:电子发烧友网 > 图书频道 > 电子 > 《微计算机原理》 > 第4章 汇编语言程序设计

第4节 8086汇编语言程序设计

 

  §4.5 8086汇编语言程序设计

  本节概述

  本节主要讲述汇编程序的几种结构。

  教学目标

  使读者掌握几种程序结构,编写程序的步骤。

  学习内容

  顺序结构

  分支结构

  循环结构

  子程序结构

  重点难点

  程序设计的几种结构。

  学习方法

  熟练掌握几种程序设计的结构。

  关键字

  顺序  分支  循环

  参考资料

  1、《微型计算机技术及应用》,戴梅萼等编著,第二版,清华大学出版社

  2、《微型计算机原理》,季维法等编著,第一版,电子科技大学出版社

  3、《微型计算机原理—常见题型解析及模拟题》,武自芳主编,西北工业大学出版社

  4、《80X86/80X87汇编语言程序设计》,洪志全等编著,电子科技大学出版社

  §4.5.1概述

  通过前面几节的介绍,我们对8086汇编语言源程序的基本概念有了比较清楚的认识,为了更高的质量、高效率地进行汇编语言程序设计,还必须很好地程序设计的方法。

  一般来说,汇编语言程序设计的技巧性是比较强的,即使对于同一个问题,不同的程序员编写出来的程序可能相差很大,这对于计算机软件的生产和推广应用都带来了极大的困难。因此,在计算机科学中提出了编制程序工程化的设计方法。集体地说,就是在软件中采用模块结构话的程序设计方法。所以,一个好的程序不仅能正常运行,完成预定任务,还应满足下列设计要求:

  (1) 正常运行,完成预定任务。

  (2) 结构清晰,程序简明、易读、易调试、易维护(修改、扩充)。

  (3) 运行速度快。

  (4) 占用内存少。

  程序执行速度快,又要占内存空间少,两者是有矛盾的,应权衡利弊,侧重某一个方面来设计。随着计算机应用的发展,程序的日渐庞大和复杂,使程序模块化,写好程序文件,以便于阅读、调试和扩展,以显得越来越重要。从程序设计整体看,可分为如下几个基本步骤:

  (1) 全面分析问题,抽象出数学模型。(有些简单问题可以根据实际经验编程)。

  (2) 确定算法。

  (3) 绘制流程图。对于复杂程序,确定需要的模块,画出模块间的结构图及各模块的流程图。

  (4) 定义数据变量,分配存储空间和工作单元。

  (5) 编写程序代码。(按所使用的语言、软件、硬件平台编写)。

  (6) 静态检查、上机调试。

  在程序设计中,为了使程序结构清晰,应采用结构化程序设计方法,常用的程序基本结构有:顺序结构、分支结构、循环结构、子程序结构。

  §4.5.2 顺序结构

  顺序结构的程序一般是简单程序,它按顺序执行,无分支、循环、转移,顺序结构的控制流程如图所示。

  §4.5.3 分支结构

  根据不同的条件,程序转移到不同的分支,分支结构的基本形式如图4-6所示。

  以条件"ZF=0"为例。

  当两个分支合并时,要特别注意第一个分支结束时,跳转到和并点如图4-7所示。

  为了避免分支及合并时出错,一般在程序框图中,标识出主要点处的标号。

  程序的分支通过转移指令来实现,因此转移指令的特点是改变程序执行顺序。转移指令已经在8086指令系统中讲到。

  §5.5.4 循环结构

  循环是在一定条件下重复执行称为"循环体"的程序段。循环前,应当给循环条件赋初值,在循环过程中,必须修改循环条件。

  根据判别循环条件的时机,有两种基本循环结构,如图4-8、图4-9:

  循环结构可以用条件转移指令(JZ、JNZ等)、循环指令(LOOP、LOOPZ等)实现。

  指令系统提供了若干条设计循环结构的循环控制指令,循环控制指令可以同时完成修改循环控制记数、检测条件并控制转移的工作。因此循环控制指令实现控制循环结构更加简便。

  循环程序设计中的重要问题是正确地控制循环,保证循环的正常执行和结束。如果循环控制哦于错,就会导致循环不能完成预定的功能,或者循环不能结束,此时称为死循环,除非特殊需要,程序中不应出下死循环。控制循环的方法通常分为两大类:

  (1)记数循环(用语循环次数已知的情况)。

  (2)条件循环(用语循环次数不确定的情况)。

  在条件循环方法中,可以根据需要设置各种丰富、灵活的条件来控制循环。

  §5.5.5子程序结构

  在大型程序中,有时,一段相同的程序多次被使用,可以把这段程序单独提出来编写,称为"子程序",需要该段程序时,用CALL指令调用子程序,这种编程处理方法,称为"子程序结构"。 相对于子程序,调用程序称为主程序。

  当主程序与子程序不在同一个代码段时,称为段间调用;当主程序与子程序在同一个代码段时,称为段内调用。子程序可以调用子程序,称为子程序"嵌套"。 子程序调用子程序的特例是子程序调用自身,称为"递归",如图4-10所示。

  子程序可以有入口参数和/或出口参数。入口参数作为主程序传递给子程序处理的数据,出口参数是子程序处理的结果。

  编写子程序的要求:

  (1)保护寄存器与工作单元

  如果子程序要用到某些寄存器或存储单元,而它们的内容在子程序返回后还需要使用。为了不破坏原有信息,应将它们的内容压入堆栈保护,或者存入一些空闲存储器单元或寄存器,返回之前再恢复这些信息。注意:数据的出栈和图栈册顺序是相反的。

  (2)正确使用堆栈

  调用程序转入子程序前,在堆栈栈顶保存了断点的地址,当子程序执行RET指令时,则将从栈顶弹出断点地址,以便返回到调用程序。如果子程序执行期间需要使用堆栈暂存数据,则必须成对地执行PUSH和POP指令,以保证执行RET指令前,堆栈栈顶恢复到刚进入到子程序时的位置,使RET指令能正确地弹出断点地址。

  (3)子程序中应有内部文档

  为了使子程序可读性好,可理解性好,便于使用,子程序中应当给出必要说明和适当的语句注释,这些说明和注释称为内部文档。

  通常子程序头部给出下列说明:

  ·子程序名

  ·功能描述:功能、性能指标等

  ·子程序的入口参数、出口参数

  ·子程序使用的寄存器、存储单元

  ·子程序所调用的其它子程序的名字

  (4)参数传递

  通过调用程序传递给子程序的参数,可以使子程序的每次调用完成不同要求的具体操作,增加子程序的灵活性。例如,一个子程序的功能是从一个任意长度的任意字符串中查找一个指定字符串出现的位置。由调用程序将两个字符串的起始地址和字符串长度传递给子程序,子程序便可完成一次具体的查找操作,然后将子字符串的位置指针再返回给调用程序。调用程序传递给子程序的参数称为入口参数,子程序返回给调用程序的数据或地址称为出口参数。正因为子程序即可以接受调用程序传递的参数,也可以返回参数给调用程序,才使子程序更加灵活、方便而具有通用性。

  §4.6 实数运算

  本节概述

  本节主要讲述实数的运算和数学处理器的编程结构和它的指令。

  教学目标

  了解实数的运算,实数的编码,数学微处理器的编程结构和它的指令。

  本节内容

  实数的运算

  实数的编码

  数学协处理器的编程结构

  CPU与数学协处理器的软件协调

  数学协处理器的指令

  实数运算程序例题

  重点难点

  实数的编码,数学微处理器的编程结构和它的指令。

  学习方法

  熟练掌握实数的编码,数学微处理器的编程结构和它的指令。

  关键字

  运算 编码  编程结构  指令

  参考资料

  1、《微型计算机技术及应用》,戴梅萼等编著,第二版,清华大学出版社

  2、《微型计算机原理》,季维法等编著,第一版,电子科技大学出版社

  3、《微型计算机原理—常见题型解析及模拟题》,武自芳主编,西北工业大学出版社

  4、《80X86/80X87汇编语言程序设计》,洪志全等编著,电子科技大学出版社

  §4.6.1实数的运算

  8086/80286/80386等X86 CPU 无实数运算指令,若要进行实数运算,可有以下两种途径:

  ① 使用8087/80287/80387数学协处理器(numeric coprocessor )。

  ② 用X86 CPU 的整数指令仿真实数运算。

  在80386及以前的系统中,数学协处理器与主处理器(CPU)分别制造为单独的芯片,两者通过外部联线相互操作,数学协处理器也称为NPX(numeric processor extension)。

  在80486及以后的系统中,一般把数学协处理器与主处理器集成到一块芯片上,整体称为CPU,集成后的数学协处理器称为该CPU的浮点运算单元FPU(float process unit)。

  §4.6.2 实数的编码

  在计算机中,任何信息均是通过编码表示的,实数也不例外。任何实数,均可规格化 (Normalized) 为:R=±1.MX2N,1为整数,M为尾数,N为指数。

  在这种表示方法中,二进制小数点的位置随指数部分移动,称为"浮点表示",因此,常将实数运算称为"浮点运算"。

  用编码表示正/负、整数、尾数、指数,则可表示一个实数。按编码使用的二进制位数不同,程序中可使用短实数、长实数和临时实数,分别用伪指令DD、DQ、DT定义。

  DD:定义一个短实数,或称单精度实数, 在内存中占32位(4字节)

  DQ:定义一个长实数,或称双精度实数, 在内存中占64位(8字节)

  DT:定义一个临时实数,或称扩展精度实数,占80位(10字节),一般用于数学协处理器内部运算。

  汇编程序MASM将以上十进制实数编码为二进制。编码的格式有两种:IEEE格式和Microsoft格式。

  以下介绍IEEE格式。

  1、 短实数的编码

  S(31)指数N(30~23),8位尾数M(BIT22~BIT0),23位

  表示的实数值R=±1.M×2(N-127)

  整数部分1是固定的,未在编码中表示出来。

  指数部分减去一个值,是为了避免出现负值。

  2、长实数的编码

  S(63)指数N(62~52),11位尾数M(BIT51~BIT0),52位

  表示的实数值R=±1.M×2(N-1023)

  整数部分1是固定的,未在编码中表示出来。

  3、临时实数的编码:

  S(79)指数N(78~64),15位1(63)尾数M(62~0),63位

  表示的实数值R=±1.M×2(N-16383)

  整数部分1用BIT63表示,便于数学协处理器运算。