《汇编语言程序设计》PPT课件.ppt
第四章 8086汇编语言程序设计,几个概念8086汇编语言的语句8086汇编中的伪指令8086汇编中的运算符汇编语言程序设计宏定义与宏调用汇编语言系统程序设计实例与上机调试,几个概念,程序是一组为完成某种功能而按一定顺序(由算法确定)编排的指令序列。本章将首先介绍8086宏汇编语言的基本语法及常用伪指令,然后用实例说明8086宏汇编语言源程序的设计方法。,1.3种语言,机器语言:当指令和数据都用二进制代码表示时,计算机能够直接识别与执行,因而称 之为机器语言。高级语言:是完全独立于机器的通用语言,效率低。面向过程、面向对象,必须译成机器语言。汇编语言:汇编语言是一种用符号表示的、面向CPU 指令系统的程序设计语言。是用指令的助记符、符号地址、标号等 编写程序的语言。,汇编语言程序是机器语言程序的符号表示,用汇编语言编写程序能够:,程序目标代码占用内存少,执行速度快,效率高,具有实时性.,直接利用硬件系统的特性(如寄存器、标志、中断系统等),直接对位、字节、字、寄存器或存储单元、I/O端口进行处理,同时也能直接使用CPU指令系统提供的各种寻址方式,编制出高质量的程序。,从源程序获得目标程序的过程,为了能顺利完成汇编,用户必须为汇编程序提供一些额外的、与硬件有关的信息.如:程序使用的变量应分别存放在内存的哪个单元、堆栈应从内存的什么地址开始等等。,2.汇编程序的作用,将源程序翻译成机器语言程序。按用户要求自动分配存储区域(如程序区、数据区等)。自动地把各种进制数 二进制数。把字符 ASCII码。计算表达式的值。自动对源程序进行检查,指出语法错误(如非法格式、未定义的助记符、标号、漏掉操作数等)。,3.汇编语言程序的上机与处理过程,汇编语言上机过程D:EDIT ABC.asmD:MASM ABC 有语法错,回EDIT下改该程序D:LINK ABC 有错,回在EDIT下改程序D:ABC 运行结果错,回EDIT下改程序 或在DEBUG下调试,找原因。D:DEBUG ABC.exe,4.1 汇编语言的程序结构与语句格式,语法语句和程序结构必须遵循的规则。源程序按其编译器能够理解的语法编 写方可。,4.1.1 汇编语言源程序的框架结构,1.源程序由若干个逻辑段组成每段由伪指令SEGMENT开始、由ENDS结束。通常有:代码段(必不可少)堆栈段建立一个堆栈区,以存放中断时的断 点地址,子程序调用时断点地址及子程序 间传递参数。数据段和附加数据段用来在内存中建立一个 适当容量的工作区用以存放数据。,一、源程序的结构特点 按逻辑段组织源程序。包括代码段、堆栈段、数据段等。,【例题4.1】实现:123+456sum 的源程序,CODESEGMENT;语句6 ASSUME CS:CODE,DS:DATAMAIN PROC FAR;语句8START:PUSH DS;语句9.;RET;语句17MAIN ENDP;语句18CODE ENDS;语句19,数据段,代码段,DATA SEGMENT;语句1 A DW 123;语句2 B DW 456;语句3 SUM DW?;语句4DATA ENDS;语句5,END START;语句20,汇编语言语法,3.每段由若干语句行组成,每行只有一条语句且不能超过128个字符,允许有后续行。整个源程序以END结束,它通知汇编程序停止汇编。END后的START标号为程序运行时的起始地址。,2.在代码段起始处,用ASSUME伪指令说明各个段Reg与逻辑段的关系,并在程序 起始处设置段Reg的初值(代码段CS除外)。,4.每条语句由4个字段构成。各字段间用空格分开。,5.源程序中设有返回DOS的指令语句,使程序执行完后返回DOS系统的命令接受状态。,二、源程序与PC DOS的接口 汇编语言源程序(.ASM)经过汇编转变为目标程序(.OBJ),当用链接程序对其进行链接和定位时,操作系统为每个用户程序建立:,一个256字节的程序段前缀区(PSP),存放用户程序信息。在PSP的开始处(偏移地址0000H)安排一条INT 20H 软中断指令。INT 20H功能是使系统返回到DOS管理状态。因此,用户执行程序完后,必须能够转到PSP起始处执行INT 20H指令。,定位用户程序 设置DS和ES的值使之指向PSP的开始处,即PSP的段地址 DS和ES。将用户程序的段基址、第一条指令的偏移地址设置CS、IP;同时设置SS、SP。运行用户程序,保证用户程序执行完后返回DOS的方法 第一种方法:标准序法 将用户程序中的主程序定义为FAR过程,其最后一条指令为RET(当程序执行到RET时,会将栈顶的两个字分别送IP、CS)在主程序的开始处将PSP的段地址和偏移地址(DS、ES和0000H)进栈保护:PUSHDS;保护PSP段地址MOVAX,0;保护偏移0地址PUSHAX;用户程序开始当用户程序返回时,会返回到DOS(执行INT 20H)。,注:由于DS、ES由DOS设置,所以在用户程序开始处应重新设置DS、ES。,第二种方法:非标准方法 不定义主程序为FAR过程,并去掉标准序。在代码段结束之前(即CODE ENDS之前)增加两句:MOVAH,4CHINT21H;4CH号的DOS系统功能调用,8086汇编语言的语句,源程序是一个语句序列,每条语句规定一个基本操作,语句 序列完成某个特定的操作任务。,一、语句的种类与格式 1.语句的种类(1)指令语句 _可执行语句,对应CPU指令系统规定的一条指令。,汇编时,汇编程序为之产生一一对应的机器目标代码。例:MOVAH,4CH INCBX,(2)伪指令语句 _汇编时给汇编程序提供与硬件有关的汇编信息,本身并不产生目标代码,CPU不执行。是指示汇编 程序进行汇编的操作。,例:MESSAGE DB THIS IS A SAMPLE PROGRAM.;定义变量MESSAGE在数据段DATA中的存放形式汇编时,汇编程序将MESSAGE定义为一个字节类型数据区的首地址,并按字节存储字符串。,2.语句格式,指令语句的一般格式:标号:前缀 指令助记符 操作数;注释 伪指令语句的格式:名字 伪指令定义符 操作数;注释,标识符字段 标识符字段由各种有效字符组成,一般表示符号地址,具有段基址、偏移量、类型三种属性。很多情况下标识符字段是语句中的可选部分,主要为便于程序的读写方便而使用。标识符字段通常有:标号 后跟冒号,在程序中作为JMP、LOOP指令的转移目标,与具体的指令地址相联系。名字 用于定义常量名、变量名、过程名、段名等。,(1)标号和名字,标号和名字必须符合汇编语言对标识符的规定:以字母开头,由字母(不分大小写)、数字(09)及部分特殊字符(?$和下划线_等)组成,字符串长度不超过31个。标识符不能是汇编语言中有特定意义的保留字、助记符、Reg等,如:CPU的内部寄存器名AH、AL、AX等。,(2)助记符、定义符 规定指令或伪指令的操作功能,是语句中唯一不可缺少的部分。,对于指令,汇编程序将其翻译成机器语言指令。MOV AX,100 B8 00 01对于伪指令,汇编程序据其要求的功能进行处理。data SEGMENT data与一段地址对应 string DB Tsinghua string与一内存地址对应,前缀仅可出现在指令助记符前。,(3)操作数 指令语句中提供给指令的操作对象、存放位置。操作数可以是1个、2个或0个,2个时用逗号,分开。(INC BX;MOV AX,DATA;RET)伪指令语句中操作数的格式和含义随伪操作指令不同而不同。,(4)注释 以“;”开始,给以编程说明。汇编程序对“;”后的内容不做处理。注释对汇编不起任何作用,不对应于任何机器码,仅增强源程序的可读性。,操作数可能为以下几种情况:常量操作数:如 34 等。寄存器操作数:如 AX 等。存储器操作数:如0100H 等。表达式操作数:如AX+2、SEG NUM1等。,4.2 8086汇编中的伪指令,指示汇编、链接程序如何进行汇编和链接,影响目标代码生成,本身不产生目标代码。有符号定义语句、数据定义语句、程序结构语句、模块链接语句、有关宏的语句、条件汇编语句等。,给表达式赋予一种符号名,以便在程序中用它替代表达式1、等值语句 格式:符号名 EQU 表达式例:PORT EQU 40H;用PORT代替40H号端口 COUNT EQU CX;用COUNT代替CX寄存器 M EQU MOV;用M代替MOV指令助记符,注:EQU语句不能重新定义,即在同一源程序中,用EQU定义过的符号不能赋予不同的值。,例:B EQU bp+8 B EQU 20H 不行!,4.2.1 符号定义语句,2、等号语句 格式:符号名 表达式 功能与EQU类似。例:PP=89FAH;赋值 PP=PP+1;PP=89FBH,注:等号语句与EQU语句的相同点:符号不是变量,所以用EQU、=定义的符号不占用存储器单元。区别:等号语句可以在同一源程序中重复定义符号。,4.2.2 变量定义语句 用于定义变量(程序中所用的存储器操作数),指定变量的类型和名称,并为其分配存储单元和预置初值。,1.格式 变量名 数据定义符 操作数,操作数,操作数 变量名指示存储器操作数的地址(符号地址)数据定义符指示存储器操作数的类型(字节、字、双字等)操作数指示存储器操作数的内容,是赋给变量的初值。多个相同类型的变量可在一条语句中定义 表示可选,汇编程序将定义的操作数,按其类型分配内存单元数,并顺序存入变量名指向的内存单元中。常用的数据定义符有:DB 变量为字节数据类型DW 变量为字数据类型,存放时低对低高对高。DD 变量为双字数据类型,存放时低对低高对高。,经过定义的变量有3种属性:段值、段内偏移量和类型。若某个变量表示的是一个数组,则其类型属性为变量的单个元素所占用的字节数。,其它的数据定义符有:DQ 变量为4字数据类型(64位)DT 变量为10字节数据类型(80位),2.具体形式和功能(1)为数据项分配存储单元,用变量名作为该存储单元的名称。例:X DB25H Y DW4142H Z DD12345678H 存储形式如图:,初始值也可以是表达式 如:IN_PORT DBPORT_VAL OUT_PORT DBPORT_VAL+1 其中,PORT_VAL已由EQU语句赋了值。,(2)预留内存单元,但不赋值,以存放运算结果.例:A DB?B DB?,(3)定义一个数组 例:W_TABLE DW 1122H,3344H B_TABLE DB 1,2,4,9,16 当表中的操作数相同时,可用重复操作符DUP来缩写:格式:重复次数 DUP(操作数)例:ALL_ZERO DB 0,0,0,0,0,0 ALL_ZERO DB 6 DUP(0),(4)定义字符串(只能用DB定义)例:MESSAGE DBHELLO 每个字符的值为它的ASCII码值,所以 用DB来定义。,例:str1 DB TsingHua str2 DB INPUT:,0dH,0aH,$,data SEGMENTxx DB 1,-1,0FCHyy DW 1,-1,0FCHzz DD 1,-1,0FCHstr DB TsingHuabuf DB 4,?,4 DUP(?)DB dataenddata ENDScode SEGMENT ASSUME CS:code ASSUME DS:datastart:MOV AX,data MOV DS,AX LEA BX,xx LEA SI,yy LEA DI,zz MOV AH,4CH INT 21Hcode ENDS END start,例:在DEBUG下查看变量存放情况。,例:XX DW CYCLE YY DD CYCLE CYCLE:MOV BX,AX;CYCLE是程序的一个NEAR标号,例:VAR3 DW VAR+1;将VAR+1的的偏移地址存入 VAR3开始的两个字节或 VAR3 DD VAR+1;将VAR+1的的全地址存入 VAR3开始的两个字,(5)将已定义的地址存放内存单元 当操作数是标号或变量时,可用DW或DD将标号或变量操作数的偏移地址或全地址来初始化存储器。,例:TABLE DB 12H,34H TAL_PS DD TABLE,4.2.3 段定义伪指令(将程序分成若干逻辑段)用于告诉汇编程序和链接程序如何按逻辑段来组织程序和利用存储器。,1.段定义语句 SEGMENT/ENDS 用于对 DS、ES、SS、CS 段的定义 格式:段名 SEGMENT 定位类型组合属性类别名(段体)段名 ENDS,功能:指出段名和段的各种属性,并表示段的开始和结束位置。,段定义由伪操作SEGMENT开始、ENDS结束。SEGMENT 和ENDS 必须成对出现,且段名必须相同。SEGMENT和ENDS语句之间可以有指令和其他伪指令,表示存放在该段内存中的变量、指令或其他伪指令对该段内存的处理 程序中可以定义多个段 程序经汇编、连接及装入内存后,段名为一具体的段值(常量值)。,(1)定位类型告诉链接程序链接时段的起始边界,有4种选择:PAGE:段起始地址必须是256的倍数(XXX00H),最低8位为0。PARA:段起始地址必须是16的倍数(XXXX0H),最低4位必须为0。WORD:段起始地址必须是偶数(XX0B),最低1位必须为0。BYTE:段起始地址为任意值,即从任何地址开始都行。缺省类型为PARA。,(2)组合类型 在多模块(每个模块有自己的代码段、数据段、堆栈段)组合时,告诉链接程序本段与其他模块中同名段的链接关系,有6种选择:NONE:本段与其它同名段逻辑上不发生关系,有自己的段基地址(缺省选择)。PUBLIC:在满足定位类型的前提下,链接程序将其与其他模块中的同名段邻接在一起,共用一个段地址。链接的先后次序由链接命令指定。,段定义的相关约定,STACK:与PUBLIC同样处理,链接后作为堆栈段,并自动初始化SS、SP,SS指向第一个STACK段。若程序中不说明STACK,则必须由用户在程序的开始处,自己通过语句设置SS、SP。COMMON:各模块中同名段重叠覆盖,有着相同的起始地 址。段的长度取决于最长的COMMON段。段的内容为所链接的最后一个模块中COMMON段的内容。AT表达式:链接程序把本段装在表达式值所指定的段地址(此方式不能指定代码段)。例:AT 0903H;本段从09030H开始存放。MEMORY:链接在其他所有段的后面(高端存储区)。若有多个MEMERY段,则只认第一个,其余按COMMON处理。,段定义的相关约定,(3)类别名给各段的名字信息,表示段的类别。类别必须用单引号括起来,典型类别名如:STACK、CODE和DATA等。若缺省类别名,则表明该段类别为空。同名同类别的段在内存中依序连续存放。,2.段寄存器说明伪指令 格式:ASSUME 段寄存器:段名,段寄存器:段名,(1)设定特定的Sreg指向特点的段,说明源程序中定义的段应由哪一个Sreg去寻址。否则,汇编程序无法生成机器代码程序。(2)ASSUME并未真正的将段地址装入相应的Sreg。Sreg的初值还必须由用户在程序的开始处用MOV指令来设置(CS除外)。,3.指定地址伪指令 ORG 在汇编程序中,有一个软件计数器(LC)地址计数器。在每个段定义开始处,它被复位为0。当汇编程序逐行扫描语句时,用LC保存当前指令的地址。格式1:ORG 表达;将表达式的值(065535)LC 格式2:ORG$+表达式;将LC的当前值$表达式的值 LC 功能:强行指定地址计数器LC的当前值,在段内改变它以后的代码或数据存放的偏移地址。,ORG语句之后段内所有的代码或数据均以表达式(常量)的值为起始偏移量连续存放,除非遇到另一个ORG语句。此语句本身并不占内存。,4.模块的定义和通信 MASM宏汇编语言提供了模块化编程伪指令,用以实现模块的定义与通信。一个任务的源程序由若干模块组成,每个模块有代码段、数据段等,对应一个.ASM,是个独立的编译单位。当各个模块编译完毕,可用LINK连接各模块形成一个完整的可执行程序(.exe)。,1).模块定义伪指令 NAME/END NAME 模块名;为模块命名;语句 END 标号;结束模块模块名的作用是指示给连接程序进行连接用。源程序中可无模块定义,此时源文件名作为模块名。主模块的END后要跟标号,子模块不跟标号。部分可省略。,2).模块间通信伪指令 实现模块间数据或过程的互访和共享。格式:PUBLIC名字,名字,EXTRN名字:类型,名字:类型,,PUBLIC 和EXTRN配对使用。由PUBLIC 说明的名字是全局的,可以在其他模块中使用,EXTRN表明本模块中使用的名字在别的模块中定义过,且类型一致。,其中,名字可以是标号、变量名、过程名或由EQU(或)伪指令定义的符号名。,类型可以是BYTE、WORD、DWORD、NEAR、FAR和ABS(常量属性)等。,格式:过程名 PROCNEAR/FAR RET 过程名 ENDP,4.2.4 过程和宏定义伪指令 过程和宏是模块化程序设计的基础。汇编语言中常用定义过程和宏的方法来实现按模块管理 程序代码的功能。,1.过程定义伪指令 过程:一段可以由CALL指令调用,用RET返回的程序。当整个源程序由主、子程序构成时,主、子程序 都在代码段,且都可用过程来表示(即定义为过程)。,功能:定义一个过程,并指出过程名及过程的属性。过程定义由伪指令PROC开始、ENDP结束。PROC和ENDP之间为过程的指令序列。程序中可以定义多个过程。程序经汇编、连接及装入内存后,过程名为一具体的内存地址,指示子程序入口。,过程的属性有NEAR和FAR NEAR过程只能被定义该过程的段中的其他程序调用(段内调用)FAR过程可由任何段中的程序调用(段间调用)缺省时为NEAR 根据过程的属性,汇编程序自动对CALL、RET翻译成段内(段间)调用及段内(段间)返回的目标代码。,COD1SEGMENTASSUME CS:COD1,;代码段中的其它语句(主程序)SUB1PROC FAR;名为SUB1的FAR过程开始 RET;返回SUB1ENDP;SUB1结束SUB2PROC;名为SUB2的NEAR过程开始 RET;返回SUB2ENDP;SUB2结束;可能定义的其它过程COD1ENDS;代码段结束,例,(1)宏定义 格式:宏指令名MACRO形参,形参:;指令序列 ENDM,宏扩展:汇编时,将相应的程序段中的每条语句前冠以“”,代替宏指令以产生目标代码。,宏调用在源程序中用宏指令代替所定义的程序段。格式:宏指令名 实参,实参,2.宏定义伪指令为减少重复编写相同语句段的工作,我们可以使用“宏”功能。宏定义是指用一个标识符(宏名)来代替一组指令序列(可同时包含指令性语句和指示性语句)宏功能的使用过程是:宏定义、宏调用、宏展开。,【例】完成2个压缩BCD数加法的宏定义,DECADD MACRO OP1,OP2 MOV AL,OP1 ADD AL,OP2 DAA MOV OPR1,AL ENDM,DECADD DL,BUFFERDECADD AREA1,AREA2,宏调用,宏定义,加号表示该语句由宏展开得到。,DECADD DL,BUFFER扩展成:+MOV AL,DL+ADD AL,BUFFER+DAA+MOV DL,AL,注:当宏调用中实参数个数和形式参数个数不等时,若实参数个数大于形式参数个数,在替换时多余的实参数不予考虑。若实参数个数小于形式参数个数,则多余的形式参数作为空(字符)或零(数字)处理。,宏展开,3.过程与宏的区别 对需重复使用的模块既可定义为过程,也可定义为宏。(1)宏:由汇编程序识别,并将宏体代码插入。过程:汇编时仅产生CALL指令代码,该代码在程序执行时完成。(2)宏可以直接传递参数。但过程传递参数的编程困难。(3)汇编成机器代码时:宏扩展增加空间开销。过程调用却能缩短源程序目标代码的长度,无论过程被调用多少次,仅增加CALL、RET代码。(4)宏体执行时并不增加时间开销。过程调用时,CALL、RET指令需保护、恢复现场和断点,增加时间开销。,4.2.5 结束语句,END伪指令:格式 END 启动地址作用:指示源程序到此结束。(汇编程序对 END 之后的语句不进行处理。源程序中必须有 END 结束语句。启动地址可是一个标号或过程名,指示程序的入口。程序装入内存后,系统跳转到入口处,开始执行程序。,常用:数值常量 2(B)、10(D)、8(Q)、16(H)的整型常量。对16:必须以数字打头,若最高位为字母AF,必须加 前缀0,以与H结尾的标识符区别(如:AH,abcdH)。字符串常量 1234 是用单引号括起来的一个或多个字符,值为字符的ASCII码值。例:A=41H AB=4142H 1234 31H,32H,33H,34H 31323334H MOV AL,G,2.Reg操作数 操作数部分是寄存器名,如:AX、SI和DS等。,4.3 8086汇编中的运算符,1.常量操作数 在运行期间不变化的量:立即数、端口地址。,(3)标号和变量都与存储器地址相关联,都具有以下三种属性:段属性(SEGMENT)段基址,标号或变量所在段的段地址。偏移量属性(OFFSET)段内偏移地址,标号或变量所在地 址与所在段的段起始地址之差。类型属性(TYPE)对变量,指变量存取单位的字节数大小。有字节(BYTE)、字(WORD)、双字(DWORD)、4字、10字节5种。对标号,指标号与使用它的指令之间的距离远近。(如:对转移指令来说,有NEAR标号或FAR标号),3.存贮器操作数 有标号与变量两种(1)标号:在代码段内 与指令地址相关联。(或某个过程起点位置相关联)(2)变量:在数据段或堆栈段内 是存放数据的存贮单元的符号地址,与各种存储器操作数 寻址方式有关。常以变量名的形式出现在程序中。,4.表达式操作数 表达式由各种操作数、运算符和操作符组成,可出现于源程序的任何地方,在汇编时计算(而不是在程序执行过程中).汇编程序对表达式进行运算后,得到一个确定的数值,再把这个数值汇编到指令中。,(1)有两类表达式 根据表达式所表示的内容而分。数值表达式:由常量及算术逻辑运算符、或关系运算符连接而成。在汇编时产生一个数值。地址表达式:由常量、变量、标号、寄存器的内容及一些运算符组成。其值表示存储器地址,有以上三种属性。,例:MOV AX,12-4;MOV AX,8;数字表达式 LEA BX,string+4;地址表达式 ES:SI+4;地址表达式,(2)运算符和操作符 MASM宏汇编中有三种运算符:算术、逻辑和关系运算符 两种操作符:分析和合成操作符 运算符:实现对操作数的相关运算。操作符:完成对操作数属性的定义、调用和修改。,主要有:1.算术运算符(+、/、MOD)2.逻辑运算符(AND、OR、NOT、XOR)3.关系运算符(EQ、NE、GT、GE、LT、LE)真:FFFFH;假:04.分析操作符(SEG、OFFSET、TYPE、SIZE、LENGTH、HIGH、LOW)5.合成操作符(PTR、DS:、THIS、SHORT),数值表达式中可使用所有算术运算符 地址表达式仅使用+、两种算术运算符 常用:标号或变量常量形式 运算后仍为标号或变量,其3个属性中的类型及 段基址属性不变,仅修改了偏移量属性。例:PLACE23;若PLACE与某存贮单元地址相关,则PLACE+23仍与某存贮单元相关。,算术运算符不影响标志位 例:完成80H+90H 解:MOV AL,80H+90H;使用数值表达式;(AL)=10H、CF=不变 MOV AL,80H;使用加法指令 ADD AL,90H;(AL)=10H、CF=1,算术运算符(+、/、MOD(取余数)MOV AX,6 8 MOV AX,48,作为运算符时,是在程序汇编时由汇编程序计算的,计算结果充当指令的某一个操作数或构成操作数的部分,作为指令助记符时,是在程序运行时被执行,操作对象可以是寄存器或存储器操作数。,注:逻辑运算符与逻辑指令助记符形同意不同,逻辑运算符AND、OR、XOR和NOT 实现操作数按位逻辑操作,只适用于数值表达式。MOV AX,80h OR 70h MOV AX,0F0h,关系运算符EQ、NE、LT、GT、LE和GE。在两个无符号操作数之间进行大小关系比较 两个操作数必须同是数值或同是一个段内的两个存储器地址。关系不成立(为假)则结果为“0”(假:0);若关系成立(为真)则结果为全“1”(真:FFFFH)。结果值在汇编时获得。例:MOV BX,PORT LT 5 汇编为:MOV BX,0FFFFH(条件成立)或 MOV BX,0000H(条件不成立),分析操作符与合成操作符 分析操作符(数值返回运算符)运算对象是存储器操作数,它返回变量或标号的属性值。合成操作符(修改属性运算符)作用于存储器操作数时可以改变它们的属性。用分析或合成操作符,可以返回或修改存储器操作数的3种属性.,例:ARRAY DB 100 DUP(0)MOV AX,SEG ARRAY MOV DS,AX;对DS初始化 MOV BX,OFFSET ARRAY MOV AL,BX,(1)分析操作符(SEG、OFFSET、TYPE、SIZE、LENGTH)使用格式:操作符 标号或变量 SEG、OFFSET返回标号或变量的段地址和偏移地址,TYPE LENGTH SIZE TYPE 返回存储器操作数(标号或变量)的类型值。LENGTH 返回变量用DUP定义的重复次数。SIZE 返回TYPE和LENGTH的乘积,表示为变量所分 配的字节存储单元总数。,例:BUFFER1 DB 100 DUP(0)BUFFER2 DW 200 DUP(20H)BUFFER3 DD 100 DUP(13)则 LENGTH BUFFER1=100 LENGTH BUFFER2=200 LENGTH BUFFER3=100,注:用LENGTH返回的存储区必须用DUP来定义,否则返回1。,使用格式:类型 PTR 标号或变量,例:ARRAY1 DB 0,1,2,3,4 ARRAY2 DW 0,1,2,3,4 MOV BX,WORD PTR ARRAY13 MOV CL,BYTE PTR ARRAY26 MOV WORD PTRSI,4,配合EQU伪指令,还可以为原变量定义新的变量名,如:ARRAY1 DB 0,1,2,3,4 ARRAY2 DW 0,1,2,3,4 WBYTE EQU WORD PTR ARRAY1 BWORD EQU BYTE PTR ARRAT2 MOV BX,WBYTE3 MOV CL,BWORD6,例:ABC DW?A1 EQU BYTE PTR ABC;A1是ABC的第一个字节 A2 EQU BYTE PTR ABC1或 A2 EQU A11 MOV AL,A1 MOV AH,A2,例,可以如下处置:MOV AX,WORD PTR OPER1+1;AX=3402H MOV AL,BYTE PTR OPER2;AL=34H MOV AL,BYTE PTR OPER2+1;AL=12H,THIS 与EQU配合使用,具有LABLE的同样作用。使用格式:标号或变量名 EQU THIS 类型 例:BWORD EQU THIS BYTE;定义字节 ARRAY DW 100 DUP(?);定义字 将原定义的字缓冲区ARRAY按字节区BWORD使用。,LABLE 为当前存储单元定义一个指定类型的标号或变量。常用于定义一个数据块或标号,使它们具有多重名字和属性。使用格式:标号或变量名 LABLE 类型,例:WBYTE LABLE WORD;为变量WBYTE定义;一个字类型的数据区 ARRAY DB 1,2,3,4 MOV AL,ARRAY;01H AL MOV AX,WBYTE;0201H AX WBYTE、ARRAY 指向同一个数据区,但有不同的类型属性。,DATASEGMENT;定义数据段D1DB 5 DUP(?);连续的字节单元CCEQU$D1;对单元计数SUMDW 0;为结果保留一个字DATAENDS;数据段定义结束STACK SEGMENT PARA STACK STACK;定义堆栈段DB 100 DUP(?);100字节的栈空间STACKENDS;堆栈段定义结束CODESEGMENT;定义代码段ASSUME DS:DATA,SS:STACK,CS:CODE;对各段进行说明BEGIN:MOV AX,DATA;DS初始化为DATAMOV DS,AXLEA SI,D1;预置源数据的指针,例 多个连续字节单元的累加,MOV CX,CC;预置次数LODS BYTE PTR SI;取一个数并修改指针MOV AH,0;清AX的高字节CLC;清CF位AGAN:ADC SUM,AX;累加LODS BYTE PTR SI;再取数并修改指针LOOP AGAN;控制循环MOV AH,4CH;完成,返回DOSINT 21HCODEENDS;代码段结束ENDBEGIN;整个程序结束,4.4 汇编语言程序设计,介绍汇编语言程序设计的常用结构与方法,与大多数高级语言相同的是:汇编语言是结构化的语言。一个大的汇编源程序可由多个“模块”组成,而每个模块则由一个或多个“段”构成。与高级语言不同,使用汇编语言编程时需同时使用指令和伪指令。,汇编源程序的基本结构形式模块和段一个汇编“模块”可以包含一个或几个长度小于64KB的“段”8086只有4个段寄存器(CS、DS、SS和ES)CS:程序段DS:数据段SS:堆栈段ES:附加段(可选),特点程序分段语句由指令性和指示性语句组成两种程序框架,框架一:DATA SEGMENT;定义数据段VAL1 DB 12H,8EH;定义变量 DATA ENDS;数据段结束 CODE SEGMENT;定义代码段 ASSUME DS:DATA,CS:CODE;段属性说明 START:MOV AX,DATA;初始化DS MOV DS,AX;填写代码 MOV AX,4C00H;返回DOS INT 21H CODE ENDS;代码段结束 END START;源程序结束,框架二:DATA SEGMENT;定义数据段VAL1 DB 12H,8EH;定义变量 DATA ENDS;数据段结束 CODE SEGMENT;定义代码段MAIN PROC FAR ASSUME DS:DATA,CS:CODE;段属性说明 START:PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX;填写代码 RETMAIN ENDP CODE ENDS;代码段结束 END START;源程序结束,4.4.1 汇编语言程序设计基本步骤,1分析问题并抽象出数学模型。2确定最佳算法。3画出程序结构框图和流程图。4合理分配内存工作单元和寄存器,并了解I/O接口地址。5编程并调试。(有时需要用注释行说明程序,便于阅读和修改。),评价程序质量的标准1合理组织数据,发挥存贮器、Reg的作用。2程序逻辑结构好,便于二次开发。3可读性强。4高可靠性和可维护性。5效率高(代码少)。,4.4.2 程序的基本结构,一、顺序结构 对应简单程序,顺序执行,无转移、无循环。指令指针IP值线性增加。二、分支结构 依据不同条件分支到各程序段,有双分支和多分支两种。IP值受标志位的影响而跳变。,三种基本结构奠定了实现任何复杂程序的基础。,三、循环结构 实现那些 需要重复做的工作。IP值因计数器CX中的值不为零而循环。,循环结构,1、顺序结构程序设计按事件发展的先后,选择合适的指令有序地加以组合。DATA SEGMENTBLOCK DW 0ABCDHBUFF DD?DATD ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV DX,BLOCK MOV AX,DX AND AX,0F0FH AND DX,0F0F0H MOV CL,4 SHR DX,CL LEA BX,BUF MOV BX+0,AL MOV BX+1,DL MOV BX+2,AH MOV BX+3,DH MOV AX,4C00H INT 21HCODE ENDS END START,例:编程计算表达式Z=X2Y/5的值,其中X、Y为带符号字节整数,Z为带符号字整数。,PUSHDSSUBAX,AXPUSHAXMOVAX,DAT MOVDS,AX,MOVAL,XIMULALMOVBX,AX,MOVAL,YCBWMOVCL,5IDIVCLCBW,SUBBX,AXMOVZ,BX,RET,例:将某段中的字符串“Hello!”传送到另一段中(内存数据块 的传送)。,利用变量定义字符串和缓冲区,思考题:压缩BCD码分解为非压缩BCD码。,aa SEGMENT;数据段1xx DB Hello!;定义源串aa ENDSbb SEGMENT;数据段2yy DB 6 dup(?);定义目的缓冲区bb ENDScc SEGMENT;代码段 ASSUME CS:cc,DS:aa,ES:bb;指示指令中标号、变量所在段start:CLD;设置传送方向 MOV AX,aa;DS:SI 源串首地址 MOV DS,AX LEA SI,xx MOV AX,SEG yy;ES:DI 目的首地址 MOV ES,AX MOV DI,OFFSET yy MOV CX,6;CX 串的长度 REP MOVSB;串传送 MOV AH,4CH;调用4CH系统功能,返回DOS INT 21H cc ENDS END start;指示程序结束和程序入口,2、分支结构程序设计,设计分支程序的关键:如何判断分支的条件 如何实现分支结构,1.利用比较和转移指令实现分支 方法:在需要分支的地方用比较指令CMP、串比较指令CMPS或串搜索指令SCAS等,进行分支条件的比较判断,再利用各种条件转移指令实现分支。,例1:编程实现下列函数的功能,其中X、Y为无符号字节数。,流程图,(AL)=(BL)?,PUSHDSSUBAX,AXPUSHAXMOVAX,DAT MOVDS,AX,CMPAL,BLJEC1JAC2,EXT:MOV Z,ALRET,MOVAL,XMOVBL,Y,C1:MOVAL,0 JMPEXT,C2:MOVAL,1 JMPEXT,MOV AL,-1,2.利用跳转表实现分支 多用于多路分支,根据表内地址分支 将需要分支的各子程序入口地址按照一定的顺序存放在 内存区域中,在主程序中根据一定的算法计算出某子程 序地址在跳转表中的位置,从而得到相应子程序的入口 地址,然后用JMP指令转去执行。,若是段内分支,每个地址在表内占2个单元(IP的值),若是段间分支,每个地址占4个单元(CS:IP的值)。,例:设有8种产品的产品编号分别为0、1、2、7,各产品的加工子程序名分别为SBR0,SBR1,SBR7。试编写由已知编号转至相应加工子程序处理的程序。子程序入口地址的地址=表基地址(BASE)+偏移量(产品编号)2,JMP BASE产品编号2;EA=BASE+产品编号2;EA=各子程序入口地址,DATASEGMENTBASE DW SBR0,SBR1,SBR2,SBR3,SBR4,DW SBR5,SBR6,SBR7;定义跳转表BNDB?;BN中存放某一产品编号DATAENDSSTACKSEGMENT PARA STACK STACKDB100 DUP(0)STACKENDSCODESEGMENTASSUME CS:CODE,DS:DATASTARTPROC FARPUSH DSMOV AX,0 PUSH AX,3、循环结构程序设计,循环程序是在满足某些条件时对一段程序的重复执行,一般由四部分组成。,基本结构形式(1)先执行后判断(dowhile)至少进入一次循环体。常用于循环次数已知时。,(2)先判断后执行 循环体可一次都不执行。常用于循环次数未知,根据具体情况找出控制循环体结束的条件时常用。,(1)先执行后判断(dowhile),DATA SEGMENTBUF DB-1,-3,5,6,