第五章汇编语言程序设计第五章汇编语言程序设计5.1源程序的基本结构汇编语言源程序的组成部分有:模块、段、子程序和宏等。一个模块对应一个目标文件,当开发较大型的应用程序时,该程序可能由若干个目标文件或库结合而成的。有关子程序的知识和宏将在后续章节介绍,本章将介绍程序段及程序结构。1段的定义微机系统的内存是分段管理的,为了与之相对应,汇编语言源程序也分若干个段来构成。8086CPU有四个段寄存器,在该系统环境下运行的程序在某个时刻最多可访问四个段,而80386及其以后的CPU都含有六个段寄存器,于是,在这些系统环境下开发的运行程序在某个时刻最多可访问六个段。5.1源程序的基本结构1段的定义不论程序在某个时刻最多能访问多少个段,在编程序时,程序员都可以定义比该段数更多的段。在通常情况下,一个段的长度不能超过64K,在80386及其以后系统的保护方式下,段基地址是32位,段的最大长度可达4G。段的长度是指该段所占的字节数:如果段是数据段,则其长度是其所有变量所占字节数的总和;如果段是代码段,则其长度是其所有指令所占字节数的总和。在定义段时,每个段都有一个段名。在取段名时,要取一个具有一定含义的段名。5.1源程序的基本结构1段的定义段定义的一般格式如下:段名SEGMENT[对齐类型][组合类型][类别]…;段内的具体内容…段名ENDS5.1源程序的基本结构2段寄存器的说明语句在汇编语言源程序中可以定义多个段,每个段都要与一个段寄存器建立一种对应关系。建立这种对应关系的说明语句格式如下:ASSUME段寄存器名:段名[,段寄存器名:段名,……]其中:段寄存器是CS、DS、ES、SS、FS和GS,段名是在段定义语句说明时的段名。在一条ASSUME语句中可建立多组段寄存器与段之间的关系,每种对应关系要用逗号分隔。例如,ASSUMECS:CODE1,DS:DATA15.1源程序的基本结构2段寄存器的说明语句上面的语句说明了:CS对应于代码段CODE1,DS对应于数据段DATA1。在ASSUME语句中,还可以用关键字NOTHING来说明某个段寄存器不与任何段相对应。下面语句说明了段寄存器ES不与某段相对应。ASSUMEES:NOTHING在通常情况下,代码段的第一条语句就是用ASSUME语句来说明段寄存器与段之间的对应关系。在代码段的其它位置,还可以用另一个ASSUME语句来改变前面ASSUME语句所说明的对应关系,这样,代码段中的指令就用最近的ASSUME语句所建立的对应关系来确定指令中的有关信息。5.1源程序的基本结构3堆栈段的说明堆栈段是一个特殊的段,在程序中可以定义它,也可以不定义。除了要生成COM型执行文件的源程序外,一个完整的源程序一般最好定义堆栈段。如果在程序中不定义堆栈段,那么,操作系统在装入该执行程序时将自动为其指定一个64K字节的堆栈段。5.1源程序的基本结构3堆栈段的说明在源程序中,可用以下方法来定义堆栈段。方法1:STACK1SEGMENTDB256DUP(?);256是堆栈的长度,可根据需要进行改变TOPLABELWORDSTACK1ENDS在源程序的代码段中,还要添加如下程序段,才能把段STACK1当作堆栈段来使用。ASSUMESS:STACK1;可在代码段的段指定语句中一起说明CLI;禁止响应可屏蔽中断MOVAX,STACK1MOVSS,AXMOVSP,OFFSETTOP;给堆栈段的栈顶寄存器SP赋初值STI;恢复响应可屏蔽中断5.1源程序的基本结构3堆栈段的说明方法2:STACK1SEGMENTSTACK;定义一个堆栈段,其段名为STACK1DB256DUP(?)STACK1ENDS上述段定义说明了该段是堆栈段,系统会自动把段寄存器SS和栈顶寄存器SP与该堆栈段之间建立相应的关系,并设置其初值,而不用在代码段对它们进行赋值。5.1源程序的基本结构4.段的基本属性在第一小节中,我们已经介绍了段定义的格式,现在对段定义中另外的一些属性“对齐类型”、“组合类型”和“类别”作以说明,这些可选项可根据需要选择书写。如果源程序中不指定某个属性,那么,汇编程序将使用该属性的缺省值。(1)对齐类型(ALIGN)对齐类型表示当前段对起始地址的要求,连接程序(LINK.EXE)按表6.1的地址格式来定位段的起始地址。在进行段定位时,会根据其定位类型进行定位的,所以,各段之间就有可能出现一些空闲字节,即可能浪费几个字节单元。段对齐类型与段起始地址之间的对应关系对齐类型起始地址(二进制)功能说明最多的空闲字节数BYTExxxxxxxxxxxxxxxxxxxx下一个字节地址0WORDxxxxxxxxxxxxxxxxxxx0下一个字地址1DWORDxxxxxxxxxxxxxxxxxx00下一个双字地址3PARAxxxxxxxxxxxxxxxx0000下一个节地址15PAGExxxxxxxxxxxx00000000下一个页地址1275.1源程序的基本结构4.段的基本属性(2)组合类型(COMBINE)组合类型是告诉连接程序如何把不同模块中段名相同的段合并在一起。具体的组合类型如下:NONE表示当前段在逻辑上独立于其它模块,并有其自己的基地址。NONE是缺省的组合类型。PUBLIC表示当前段与其它模块中同段名的PUBLIC类型段组合成一个段。组合的先后次序取决于LINK程序中目标模块排列的次序。在组合时,后续段的起始地址要按其对齐类型进行定位,所以,同名段之间可能有间隔。COMMON表示当前段与其它模块中同名段重叠,也就是说,它们的起始地址相同。最终段的长度是同名段的最大长度。由于段覆盖,所以,前一同名段中的初始化数据被后续段的初始数据覆盖掉。STACK组合类型STACK表示当前段是堆栈栈,其组合情况与PUBLIC相同。AT数值表达式该数值表达式是当前段所指定的绝对起始地址的段地址。5.1源程序的基本结构4.段的基本属性(3)类别(CLASS)类别是一个由程序员指定的用单引号括起来的字符串。如果一个段没有给出类别,那么,这个段的类别就为空。类别是用于段的分类,连接程序利用该类别来调整同名、同类别的段,并使它们相邻。典型的类别是Data和Code。如果指定某段的类别是Code,那么,该段最好是代码段,这样,有的调试程序(如:CodeView)就可以顺序工作。例如:DATA1SEGMENTWORDPUBLICData…DATA1ENDS上述段定义说明了该段的起始地址是下一个字地址、组合类型为PUBLIC、段类别是Data。5.1源程序的基本结构4.段的基本属性(4)段组(GROUP)段组伪指令GROUP是用于把源程序模块中若干个段结合成一个组,并对该段组定义一个段组名。段组伪指令的格式如下:段组名GROUP段名[,段名,……]其中:段名之间要用逗号间隔,段名也可以用表达式“SEG变量”或“SEG标号”。第五章汇编语言程序设计5.2汇编语言程序设计的基本方法和步骤1汇编语言程序设计基本步骤一般来说,编制一个汇编语言程序的步骤如下:①分析题意,确定算法或算法思想。①根据算法画出流程图,简单的情况也可不画。②分配存储空间和工作单元,合理地使用寄存器。③根据流程图编写程序。④上机调试运行程序。⑤编写说明文件第五章汇编语言程序设计5.2汇编语言程序设计的基本方法和步骤2结构化程序的概念结构化程序设计由迪克斯特拉(E.W.dijkstra)在1969年提出,是以模块化设计为中心,将待开发的软件系统划分为若干个相互独立的模块,这样使完成每一个模块的工作变单纯而明确,为设计一些较大的软件打下了良好的基础。由于模块相互独立,因此在设计其中一个模块时,不会受到其它模块的牵连,因而可将原来较为复杂的问题化简为一系列简单模块的设计。模块的独立性还为扩充已有的系统、建立新系统带来了不少的方便,因为我们可以充分利用现有的模块作积木式的扩展。第五章汇编语言程序设计5.2汇编语言程序设计的基本方法和步骤2结构化程序的概念按照结构化程序设计的观点,任何算法功能都可以通过由程序模块组成的三种基本程序结构的组合:顺序结构、选择结构和循环结构来实现。结构化程序设计的基本思想是采用自顶向下,逐步求精的程序设计方法和单入口单出口的控制结构。自顶向下、逐步求精的程序设计方法从问题本身开始,经过逐步细化,将解决问题的步骤分解为由基本程序结构模块组成的结构化程序框图;单入口单出口的思想认为一个复杂的程序,如果它仅是由顺序、选择和循环三种基本程序结构通过组合、嵌套构成,那么这个新构造的程序一定是一个单入口单出口的程序。据此就很容易编写出结构良好、易于调试的程序来。第五章汇编语言程序设计3流程图画法规定程序流程图是程序分析中最基本、最重要的分析技术,它是进行流程程序分析过程中最基本的工具。是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。(1)符号用法第五章汇编语言程序设计3流程图画法规定(2)使用约定图的布局流程图中所用的符号应该均心地分布,连线保持合理的长度,并尽量少使用长线。符号的形状流程图中多数符号内的空白供标注说明性文字。使用各种符号应注意符号的外形和各符号大小的统一,避免使符号变形或各符号大小比例不一。符号内的说明文字应使符号内的说明文字尽可能简明。通常按从左向右和从上向下方式书写,并与流向无关。如果说明文字较多,符号内写不完,可使用注解符。若注解符干扰或影响到图形的流程,应将正文写在另外一页上,并注明引用符号。第五章汇编语言程序设计3流程图画法规定符号标识符为符号规定标识符是为了便于其它文件引用该符号。便如,程序清单中引用到流程图中的特定符号。符号标识符一般写在符号的左上角.符号描述符为便于进一步理解符号的功能,可标注符号描述符。通常描述符写在符号的右上角.详细表示在处理符号或数据符号中画一横线,表明该符号在同一文件集中的其它地言有更为详细的表示。横线在符号内靠近项端,详细表示的标识符写在符号内横线之上。端点符用作详细表示的开始符号和结束符号,在此符号中应给出加横线符号中的标识符。第五章汇编语言程序设计5.2汇编语言程序设计的基本方法和步骤流线标准流向与箭头的使用流线的交叉流线的汇集符号流线进出连接符多出口判断的两种表示方法直接从判断符号引出多条流线从判断符号引出一条流线,再从它引出多条流线第五章汇编语言程序设计5.3顺序程序设计顺序程序设计是完全按照指令的书写顺序而执行每一条指令,它没有分支、循环和转移。是指令中最简单,最常见的程序结构,它的特点是结构简单,易于理解,但只适合于处理简单问题的场合。实际应用中,完全采用顺序结构的程序并不多。顺序结构程序流程图如下:S1S2S3第五章汇编语言程序设计5.3顺序程序设计1.顺序程序设计举例【例1】试编写一程序计算以下表达式的值。w=(v-(x*y+z-540))/x式中x、y、z、v均为有符号字数据。【例2】已知某班学生的英语成绩按学号(从1开始)从小到大的顺序排列在TAB表中,假定要查询的学生的学号放在变量NO中,请将查得的结果放在变量ENGLISH中。试编写程序。【例3】假设有二个字变量word1和word2,编写程序段实现交换其值的功能。【例4】试编写一个程序,把压缩存放的BCD码,转换为其对应十进制数字的ASCII码。第五章汇编语言程序设计5.3顺序程序设计2.用简单查表法实现代码转换在汇编语言程序设计中,代码转换是经常的事。上面的把BCD码转换成ASCII码就是一例。对于各种不同代码之间的转换,往往要采用各种不同的方法,以便获得最佳效率。查表是实现代码转换的方法之一,下面介绍的简单查表法是一种计算查表方法,适用于代码集合较小且转换关系复杂的场合。第五章汇编语言程序设计5.3顺序程序设计2.用简单查表法实现代码转换【例】编写一个把16进制数字码转换为对应七段代码的程序。七段显示数码管示意图如下:0123456第五章汇编语言程序设计5.3顺序程序设计2.用简单查表法实现代码转换利用上