




已阅读5页,还剩222页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四章 汇编语言程序设计,4-1. 汇编语言程序格式 4-2. MASM中的表达式 4-3. 伪指令语句 4-4. DOS系统功能调用 4-5. 程序设计方法 4-6. 宏汇编和条件汇编,汇编语言的基本概念,1机器语言(Machine Language) 机器语言是一种用二进制表示指令和数据,能被机器直接识别的计算机语言。它的缺点是不直观,不易理解和记忆,因此编写、阅读和修改机器语言程序都比较繁琐。但机器语言程序是计算机惟一能够直接理解和执行的程序,具有执行速度快、占用内存少等特点。,2高级语言(High Level Language) 如果说机器语言是面向机器的,那么高级语言(如BASIC,FORTRAN等)则是“面向过程”的语言。利用这些语言编程,程序员可以完全不考虑机器的结构特点,不必了解和熟记机器的指令系统,仅使用一些接近人们书写习惯的英语和数学表达式形式的语句去编制程序。这样编写的程序与问题本身的数学模型之间有着良好的对应关系,可在各种机器上通用(不同机器之间仅做少量修改)。但是,这种用高级语言编写的源程序并不能在机器上直接执行,需要被翻译成对应的目标程序(即机器语言程序),机器才能运行。把具有这种翻译作用的程序称为解释程序或编译程序,见下图。,由于高级语言程序是在未考虑机器的结构特点的条件下编写的,因而它就不能充分利用某种具体CPU所具有的某些特性,而通过编译或解释程序生成的目标程序往往比较冗长, 占有较多的内存空间,执行时间也比较长,这就限制了它在某些场合下的运用。例如,实时的数据采集、检测和在线的实时控制等,往往要求程序的目标代码尽可能少占内存并有尽可能快的执行速度,在这些场合下,使用高级语言编写的程序常常不能满足要求。,3汇编语言(Assembly Language) 汇编语言是一种采用助记符表示的程序设计语言,即用助记符来表示指令的操作码和操作数,用标号或符号代表地址、常量或变量。助记符一般都是英文字的缩写,以方便人们书写、阅读和检查。实际上,用汇编语言编写的汇编语言源程序就是机器语言程序的符号表示,汇编语言源程序与其经过汇编所产生的目标代码程序之间有明显的一一对应关系,故也称汇编语言为符号语言。,用汇编语言编写程序能够直接利用硬件系统的特性(如寄存器、标志、中断系统等)直接对位、字节、字寄存器或存储单元、I/O端口进行处理,同时也能直接使用CPU 指令系统和指令系统提供的各种寻址方式,编制出高质量的程序,这样的程序不但占用内存空间少,而且执行速度快。当然,由于源程序和所要解决的问题的数学模型之间的关系不够直观,使得汇编语言程序设计需要较多的软件开发时间,也增加了程序设计过程中出错的可能性。 用汇编语言编写的源程序也需要翻译成目标程序才能被机器执行。这个翻译过程称为汇编,完成汇编任务的程序称为汇编程序,见图5.2。,汇编程序的功能示意图,汇编程序是最早也是最成熟的一种系统软件。它除了能够将汇编语言源程序翻译成机器语言程序这一主要功能外,还能够根据用户的要求自动分配存储区域(包括程序区、数据区、暂存区等);自动地把各种进位制数转换成二进制数,把字符转换成ASCII码,计算表达式的值等;自动对源程序进行检查,给出错误信息(如非法格式,未定义的助记符、标号,漏掉操作数等)等。具有这些功能的汇编程序又称为基本汇编(或小汇编ASM)。 在基本汇编的基础上,进一步允许在源程序中把一个指令序列定义为一条宏指令的汇编程序,就叫做宏汇编(MASM)。它包含全部ASM功能,还增加了宏指令、结构、记录等高级汇编语言功能。,5.2 汇编语言源程序的格式,例5.1 要求将两个5字节十六进制数相加,可以编写出以下汇编语言源程序。,DATA SEGMENT ;定义数据段 DATA1 DB 0F8H,60H,0ACH,74H,3BH ;被加数 DATA2 DB 0C1H,36H,9EH,0D5H,20H ;加数 DATA ENDS ;数据段结束 CODE SEGMENT ;定义代码段 ASSUME CS:CODE,DS:DATA,START: MOV AX,DATA MOV DS,AX ;初始化DS MOV CX,5 ;循环次数送CX MOV SI,0 ;置SI初值为0 CLC ;清CF标志 LOOPER: MOV AL,DATA2SI ;取一个字节加数 ADC DATA1SI,AL ;与被加数相加,INC SI ;SI加1 DEC CX ;CX减1 JNZ LOOPER ;若不等于0,转LOOPER MOV AH,4CH INT 21H ;返回DOS CODE ENDS ;代码段结束 END START ;源程序结束,DATA SEGMENT ARRAY1 DB 05,0A2H,00,10H,85H N EQU 5 ARRAY2 DB N DUP(?) DATA ENDS STACK SEGMENT PARA STACK STACK DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS: DATA,SS:STACK BEGIN: MOV AX, DATA MOV DS, AX LEA SI, ARRAY1 LEA DI, ARRAY2 MOV CX, N,AGAIN: MOV AL, SI INC SI CMP AL, 50 JBE NEXT MOV DI, AL INC DI NEXT: DEC CX JNZ AGAIN MOV AH, 4CH INT 21H CODE ENDS END BEGIN,由上面的例子可以看出,一个完整的汇编程序编写格式要包括以下几部分:段定义、段分配、设置段地址、返回DOS语句及程序结束。 汇编语言源程序的结构是分段结构形式,一个汇编语言源程序由若干段(SEGMENT)组成,每个段以SEGMENT语句开始,以ENDS语句结束。整个源程序的结尾是END语句。 这里所说的汇编语言源程序中的段与前面讨论的CPU管理的存储器的段,既有联系,又在概念上有所区别。我们已经知道,微处理器对存储器的管理是分段的,因此,在汇编语言程序中也要求分段组织指令、数据和堆栈,以便将源程序汇编成为目标程序后,可以分别装入存储器的相应段中。,但是,以8086/8088 CPU为例,它有四个段寄存器(CS,ES,SS和DS),因此CPU对存储器按照四个物理段进行管理,即数据段、附加段、堆栈段和代码段。任何时侯CPU只能访问四个物理段。而在汇编语言源程序中,设置段的自由度比较大。例如,一个源程序中可以有多个数据段或多个代码段等等。一般来说,汇编语言源程序中段的数目可以根据实际需要而设定。为了和CPU管理的存储器物理段相区别,我们将汇编语言程序中的段称为逻辑段。在不致发生混淆的地方,有时简称为段。,在上面的简单源程序中只有三个逻辑段,一个逻辑段的名字是DATA,其中存放着与程序有关的数据,称为逻辑数据段;另一个逻辑段的名字是STACK,只申请了一定的存储器空间,称为逻辑堆栈段。第三个逻辑段的名字是CODE,其中包含着程序的指令,称为逻辑代码段。 每个段内均有若干行语句(STATEMENT),因此,可以说一个汇编源程序是由一行一行的语句组成的。下面我们来讨论汇编语言语句的类型和组成。,4-1 汇编语言程序格式,一、 指令语句 特点:与机器指令相对应。汇编程序可将他翻译成目标代码(机器指令代码)。CPU 可以执行的能完成特定功能的语句。,汇编语言源程序中的语句可以分为两种类型: 指令语句和伪指令语句。,格式: 标号: 指令助记符 操作数,操作数 ;注释,是CPU指令系统中指令的助记符,如MOV、ADC等。助记符约有90多种,在第3章中已经进行了详细的讨论。,二、伪指令语句,特点:没有对应的机器指令,它是一种不产生目标代码的语句,它仅仅在汇编过程中告诉汇编程序应如何汇编。例如,告诉汇编程序已写出的汇编语言源程序有几个段,段的名字是什么;定义变量,定义过程,给变量分配存储单元,给数字或表达式命名等。显然,伪指令语句是汇编程序在汇编时使用的。,格式: 名字 伪指令指示符 操作数,操作数 ;注释,功能:数据定义、存储区分配、段定义、段分配、指示程 序结束等。,可以是变量名、段名、过程名。名字后面通常不跟 “:”。名字后面冒号,这是它和标号的一个明显区别。,汇编程序规定的符号,常用的有变量定义语句(DB、DW),符号定义语句(EQU、=),段定义语句(SEGMENTENDS),段分配语句(ASSUME),结构定义语句(STRUCENDS),过程定义语句(PROCENDP)等类型。,不同的伪指令对操作数的要求不同。,名字和标号是由一串字符构成,用于一段程序、一组(或一个)数据或一个段的开头。使用时要注意以下3点: 标识符可由数字、字母和下划线组成; 不能以数字开头,数字可用在非开头的其它位置; 其最大长度为31个字符。,所有8086/8088的指令、伪指令和寄存器名都是保留字。 如AX、MOV、DB、INT、EQU等等。 保留字不能用作标识符,三、数据项(操作数),汇编语言中使用的操作数可以是常数、寄存器、存储器、 变量、标号和表达式。其中常数、变量和标号是三种基本的数据项。,1. 常数,常数就是指令中出现的那些固定值,可以分为数值常数和字符串常数两类。例如,立即数寻址时所有的立即数、直接寻址时所有的地址、ASCII字符串等都是常数。常数是除了自身的值以外,没有其他属性的数值。在源程序中,数值常数按其基数的不同,可有二进制数、八进制数、十进制数、十六进制数等几种不同表示形式。汇编语言用不同的后缀加以区别。,还应注意,汇编语言中的数值常数的第一位必须是数字,否则汇编时将被看成是标识符,如常数B7H应写成0B7H,FFH应写成0FFH。字符串常数是由单引号括起来的一串字符。例如ABCDEFG和179。单引号内的字符在汇编时都以ASCII的代码形式存放在存储单元中。如上述两字符串的ASCII代码为41H,42H,43H,44H,48H和31H,37H,39H。字符串最长允许有255个字符。,2. 变量,变量通常指数据存放在存储单元中的值,在程序中是可以 修改。变量都具有三种属性。,(2) 段内偏移地址(OFFSET):变量所在地址与所在段的 段基址之间的地址偏移字节数;,又称变量的段属性是变量所代表的数据区所在段的段地址。由于数据区一般在存储器的数据段中,因此变量的段地址常常在DS和ES寄存器中。,(1) 段值(SEGMENT):变量所在段的段基址;,(3) 类型(TYPE):变量的类型属性是指变量中每个元素 所包含的字节数。字节变量(BYTE)、字变量(WORD)、双字变量 (DWORD)、QWORD (四字)、TBYTE(十字)等。表示数据区中存取 操作对象的大小。,又称变量的偏移量属性。表示标号所在段的起始地址到定义该标号的地址之间的字节数。偏移量是一个16位无符号数。,又称标号的类型属性。,3. 标号,标号是可执行语句的地址的符号表示,代表一条指令的符 号地址,它可作为转移指令、调用指令CALL的以及循环控制 LOOP指令目的操作数,以确定程序转向的目的地址。 它具有三种属性。,(1) 段值(SEGMENT):标号所在段的段基址;,(2) 段内偏移地址(OFFSET):标号所在地址与所在段的 段基址之间的地址偏移字节数。,又称标号的段属性。是定义标号在程序段的段地址。当程序中引用一个标号时,该标号的段值应在CS寄存器中。,又称标号的偏移量属性。表示标号所在段的起始地址到定义该标号的地址之间的字节数。偏移量是一个16位无符号数。,(3) 类型(TYPE):标号的类型属性是指在转移指令中标 号可转移的距离(距离属性NEAR,FAR)。若标号后面紧跟冒号, 表示隐含此标号距离属性为NEAR,也可用伪指令将此属性改为 FAR。,又称标号的类型属性。NEAR可以在段内被引用,地址指针为2字节;FAR可以在其他段被引用,地址指针为4字节。如果定义一个标号时后跟冒号。,42 MASM中的表达式,MASM中使用了6类运算符: 算术运算符(Arithmetic Operators) 逻辑运算符(Logical Operators) 关系运算符(Relational Operators) 数值返回运算符(Value-Returning Operators) 修改属性运算符(Modifing attribute Operators) 其它运算符(Other Operators),表达式由运算对象及运算符组成,在汇编时由汇编程序对它进行运算,运算结果作为一个语句的操作数使用。运算对象可以是常数、变量或标号,得到的运算结果可以是一个常数字,也可以是一个存储器的地址,在此地址中存放了数据(称为变量)或指令。,一、算术运算符,例:,ARRAY DB 1,2,3,4,5,6,7,8,9 TRY DB 10,20 MOV AX, 10*2 MOV CX, TRY-ARRAY,汇编时,计算表达式形成指令为: MOV AX, 20 MOV CX, 9,例:,DA EQU 200 MOV AX, DA-80 MOV BX, DA MOD 100 MOV CX, DA/100 MOV DH, 01100100B SHR 2,汇编时,计算表达式形成指令为: DA EQU 200 MOV AX, 120 MOV BX, 0 MOV CX, 2 MOV DH, 19H,二、逻辑运算符,例: MOV AL , NOT 0FFH MOV BL, 8CH AND 73H MOV AH, 8CH OR 73H MOV CH, 8CH XOR 73H,汇编时,计算表达式形成指令为: MOV AL, 0 MOV BL, 0 MOV AH, 0FFH MOV CH, 0FFH,三、关系运算符,例: MOV AX , 10H GT 16 ADD BL, 6 EQ 0110B MOV CX, (PORT LT 5) AND 100) OR (PORT GE 5) AND 200),汇编时,计算表达式形成指令为(设PORT5): MOV AX, 0 MOV BL, 0FFH MOV CX, 200,四、数值返回运算符,1. OFFSET 格式:OFFSET 变量或标号 功能:返回变量或标号的偏移地址值,例: MOV BX , OFFSET DA1 相当于指令: LEA BX, DA1,2. SEG,格式:SEG 变量或标号 功能:得到一个标号或变量所在段的段地址。,例: MOV AX,SEG ARRAY MOV DS,AX,将变量ARRAY的段地址送DS寄存器,例: MOV AX,SEG ARRAY MOV DS,AX,3. TYPE 格式:TYPE 变量或标号 功能:返回变量的类型属性。,3. TYPE,格式:TYPE 变量或标号 功能:返回变量的类型属性。,例:,DA1 DB 11H, 22H DA2 DW 11H, 22H DA3 DD ? PRO: MOV AH, TYPE DA1 MOV AL, TYPE DA2 MOV BH, TYPE DA3 MOV BL, TYPE PRO,汇编时形成指令为: MOV AH, 1 MOV AL, 2 MOV BH, 3 MOV BL, 0FFH,4. LENGTH,格式:LENTH 变量 功能:如果一个变量已用重复操作符DUP说明其变量的个数, 则利用LENGTH 运算符可得到这个变量的个数。如果未 用DUP说明,则得到的结果总是1。,例: M1 DW 20 DUP(?) M2 DW 11,22,33 M3 DB ASDF MOV CX, LENGTH M1 MOV BL, LENGTH M2 MOV AL, LENGTH M3,汇编时,形成指令为: MOV CX, 20 MOV BL, 1 MOV AL, 1,5. SIZE,格式:SIZE 变量 功能:如果一个变量已用重复操作符DUP说明,则利用SIZE 运算符可得到分配给该变量的字节总数。如果未用DUP 说明,则得到的结果是TYPE运算的结果。,例: M1 DW 20 DUP(?) M2 DW 11,22,33 M3 DB ASDF MOV CX, SIZE M1 MOV BL, SIZE M2 MOV AL, SIZE M3,汇编时,形成指令为: MOV CX, 40 MOV BL, 2 MOV AL, 1,SIZE=LENGTH*TYPE,例: 设有数据段中使用 DATA1 DB ? 定义了一个单元,则 MOV AL, DATA1 可将DATA1中的数传送到AL中, AL=05 MOV AX, SEG DATA1 可将DATA1的所在段地址传到AX中,AX=2000 MOV AX, OFFSET DATA1 可将DATA1的偏移地址传入AX中, AX=1500 例: 设有数据段中使用 DATA1 DW 100 DUP (?) 定义了100个字单元,则 MOV AX, TYPE DATA1 ;AX=2 MOV AX, SIZE DATA1 ;AX=200 MOV AX, LENGTH DATA1 ;AX=100,05 A2 00 10 85,DS,CS,DATA1,2000:1500,五、修改属性运算符,又称综合运算符(Synthetic operators) 可以在程序运行过程中,通过修改属性运算符来修改变 量或标号的属性,包括段属性、偏移地址属性、类型属性等。,1. 段操作符,格式:段前缀: 变量或地址表达式 功能:运算符“:”(冒号)跟在段寄存器名(DS,ES,SS和CS) 之后,表示段超越,用以给一个存储器操作数指定一 个段属性,而不管其原来隐含的段是什么。,例如: MOV AX,ES:DI,2. PTR,格式:类型/距离 PTR 变量或标号 功能: PTR运算符可以指定或修改存储器操作数的类型。,例如: INC BYTE PTRBXSI 指令中利用PTR运算符明确规定了存储器操作数的类型是BYTE(字节),因此, 本指令将一个字节型存储器操作数加1。,如: DATA1 DW 100 DUP(?),05 A2 00 10 85,DS,MOV AL, DATA1 MOV AL, BYTE PTR DATA1,DATA1,利用PTR运算符可以建立一个新的存储器操作数,它与原来的同名操作数具有相同的段和偏移量,但可以有不同的类型。不过这个新类型只在当前语句中有效。 例如: STUFF DD ? ;定义STUFF为双字类型变量 MOV BX,WORD PTR STUFF ;从STUFF中取一个字到BX,也可以用PTR改变距离属性。 例如: JMP FAR PTR LOP 在JMP语句中将标号LOP改为FAR,使JMP指令安排在其它代码段中也可以使用,以实现段间转移。,3. THIS,格式:变量/标号 EQU THIS 类型/距离 功能: THIS的功能是将EQU THIS右边的类型/距离属性赋给 左边的变量/标号,该变量或标号的段地址和偏移地址 与下一个存储单元的地址相同。,使用THIS运算符可以使标号或变量更具灵活性。 例如,要求对同一个数据区既可以字节为单位,又可以字为单位进行存取,则可用以下语句: TAB1 EQU THIS WORD TAB2 DB 100 DUP(?),本例中TAB1和TAB2实际上代表同一个数据区,其中共有100个字节,但TAB1的类型为WORD(字类型),而TAB2的类型为BYTE(字节类型)。,DATA1 SEGMENT WBUFFER EQU THIS WORD BUFFER DB 12H, 34H, 00H, 91H DATA1 ENDS CODE1 SEGMENT ASSUME CS: CODE1, DS: DATA1 START: MOV AX, DATA1 MOV DS, AX LEA SI, BUFFER MOV DI, OFFSET WBUFFER MOV AL, BUFFER3 MOV BX, WBUFFER2 CODE1 ENDS END START,THIS用来建立新的存储器地址操作数,但不分配存储单元。新的操作 数类型在THIS中指定,而其段地址和偏移量就是汇编时的当前值。,12 34 00 91 85,DS,BUFFER,WBUFFER,SI=36ABH,DI=36ABH,例如,LOP EQU THIS FAR LOP1: MOV AX, 10,此时MOV AX, 10前有标号LOP,并赋予FAR属性,允许其它段的JMP指令跳到LOP标号地址上。,4. SHORT,格式:SHORT 标号 功能: SHORT运算符指定一个标号的类型为SHORT(短标号),即 标号到引用该标号指令之间的距离在128+127个字节 的范围内。短标号可以被用于无条件转移指令中。使用 短标号的指令比使用缺省的近标号的指令少一个字节。,5. HIGH和LOW,格式:HIGH/LOW 变量或标号 功能: HIGH和LOW称为字节分离运算符,对一个数或地址表达 式,HIGH从中分离出高位字节,LOW分离出低位字节。,例如: K1 EQU 0AF12H K2 EQU 3456H MOV AH, HIGH K1 MOV AL, LOW K2,汇编时,形成指令为: MOV AH, 0AFH MOV AL, 56H,六、其它运算符,1. 圆括号(),功能:用来改变运算符的优先级别,()中的运算符具有最 高级别。,例如: ARRAY DB 1,2,3,4,5,6,7,8,9 TRY DB 10,20 MOV BX, OFFSET ARRAY MOV AL, BX+2 ;03HAL MOV TRY1 , AL ;03HTRY的第二个单元,2. 方括号 ,功能:用来表示地址表达式或多重变量的下标值。,用 表示地址表达式,用 表示多重变量的下标,3. 尖括号, 及圆点 (在结构中解释),4. MASK和WIDTH (在记录中专用),七、优先级,以上介绍了表达式中使用的各种运算符,如果一个表达式同时具有多个运算符,则按以下规则运算: 优先级高的先运算,优先级低的后运算。 优先级相同时按表达式中从左到右的顺序运算。 括号可以提高运算的优先级,括号内的运算总是在相邻的运算之前进行。,运算符的优先级,4-3. 伪指令语句,伪指令无论表示形式或其在语句中所处的位置,都与指令相似。但二者之间有着重要的区别。首先,指令是给CPU的命令,在运行时由CPU执行,每条指令对应CPU的一种特定的操作,例如传送、加法等;而伪指令是给汇编程序的命令,在汇编过程中由汇编程序进行处理,例如定义数据、分配存储区、定义段以及定义过程等。其次,汇编以后,每条指令产生一一对应的目标代码;而伪指令则不产生与之相应的目标代码。主要完成变量定义、内存分配、指示程序开始和结束等。 宏汇编程序MASM提供了几十种伪指令,其中有一些伪指令小汇编ASM不能支持,如宏处理其等。根据其功能,伪指令大致可以分为以下几类:,此外还有以下不常用的语句: 群定义语句GROUP 结构定义语句STRUCENDS 记录定义语句RECODE, 数据定义语句:DB、DW、DD、DQ、DT 标号赋值语句:EQU、 段定义语句:SEGMENTENDS 段分配语句:ASSUME 过程定义语句:PROC ENDP 程序开始、结束语句:ORG、END、NAME,一、 数据定义语句 数据定义语句用于为数据分配相应的存储单元。用一个符号名代表一个或一些单元,并可为这个或这些单元提供初始值。定义数据的操作符有: 字节定义DB 字定义DW 双字定义DD 四字定义DQ 十字节定义DT 重复定义 m DUP(n)_ (重复m次个数据 n ) 与数据相联系的符号名称为变量。,格式:变量名 助记符 操作数,操作数 ;注释 变量名 助记符 n DUP (操作数,操作数) ;注释,功能:定义一个变量的类型,给变量赋初值,或者仅仅给变量 分配存储单元,而不赋予特定的值。数据定义伪指令有 DB,DW,DD,DF,DQ,DT等,而常用的是前三种。,(1). DB (Define Byte) 定义变量的类型为字节(BYTE),给变量分配字节或字节串。 DB伪指令定义符后面的操作数每个占有1个字节。 (2)DW (Define Word) 定义变量的类型为字(WORD)。DW伪指令定义符后面的操作数每个占有1个字,即2个字节。在内存中存放时,低位字在前,高位字在后。,(3)DD (Define Double word) 定义变量的类型为双字(DWORD)。DD后面的操作数每个占有2个字,即4个字节。在内存中存放时,低位字在前,高位字在后。 数据定义伪指令定义符后面的操作数可以是常数、表达式或字符串,但每项操作数的值不能超过由伪指令定义符所定义的数据类型限定的范围。例如,DB伪指令定义数据的类型为字节,则其范围为无符号数:0255;带符号数:128+127,等等。字符串必须放在单引号中。另外,超过两个字符的字符串只能用DB伪指令定义。请看下列语句:,DATA DB 101,0F0H ;存入65H,F0H EXPR DB 2*8+7 ;存入17H STR DB WELCOME! ;存入8个字符的ASCII码值 AB DB AB ;存入41H,42H BA DW AB ;存入42H,41H ABDD DD AB ;存入42H,41H,00,00 OFFAB DW AB ;存入变量AB的偏移地址 ADRS DW STR,STR3,STR5 ;存入3个偏移地址 TOTAL DD DATA ;先存DATA的偏移地址,再存段地址,设DATA的地址为1000:0200H,设DATA的地址为1000:0202H,设DATA的地址为1000:0203H,设DATA的地址为1000:020AH,设DATA的地址为1000:020CH,以上第一和第二句中,分别将常数和表达式的值赋予一个变量。 第三句的操作数是包含8个字符的字符串(只有DB伪指令才能用)。在第四、五、六句,注意伪指令DB、DW和 DD的区别,虽然操作数均为 AB 两个字符,但存入变量的内容各不相同。第七句的操作数是变量AB,而不是字符串,此句将AB的16位偏移地址存入变量OFFAB。 第八句存入三个等距的偏移地址,共占6字节。第九句中的 DD 伪指令定义符将 DATA 的偏移地址和段地址顺序存入变量TOTAL,共占2个字。,除了常数、表达式和字符串外,问号“?”也可以作为数据定义伪指令的操作数,此时仅给变量保留相应的存储单元,而不赋予变量某个确定的初值。 当同样的操作数重复多次时,可用重复操作符“DUP”表示,其形式为: n DUP(初值 ,初值,) 其中圆括号中为重复的内容,n为重复次数。如果用“n DUP(?) ”作为数据定义伪指令定义符的惟一操作数,则汇编程序产生一个相应的数据区,但不赋任何初值。重复操作符“DUP”可以嵌套。下面是用问号或“DUP”表示操作数的几个例子:,FILLER DB ? SUM DW ? DW ?,?,? BUFFER DB 10 DUP(?) ZERO DW 30 DUP(0) MASK DB 5 DUP(OK!) ARRAY DB 100 DUP(3 DUP(8),6),其中第一、第二句分别给字节变量FILLER和字变量SUM分配存储单元,但不赋予特定的值。第三句给一个没有名称的字节变量赋予3个不确定的值。第四句给变量BUFFER分配10个字节的存储空间,但不赋任何初值。第五句给变量ZERO分配一个数据区,共30个字(即60字节),每个字的内容均为零。第六句定义一个数据区,其中有5个重复的字符串OK!,共占15字节。最后一句将变量ARRAY定义为一个数据区,其中包含重复100次的内容:8,8,8,6,共占400个字节。,通常把用DUP作为惟一操作数而定义的变量称为数组。 下面是几个错误的数据定义伪指令语句: ERROR1: DW 99 ;变量名后有冒号 ERROR2 DB 25*90 ;DB的操作数超过255 ERROR3 DW 1234 ;DW的操作数是超过2个字 ;符的字符串,例: DATA1 DB ? DATA2 DW 1000H DATA3 DD 3000A455H DATA4 DB 4 DUP(0) DATA5 DW 0120H, 0240H, 0360H 通过上述定义,在存储器中将产生如图所示的结果,以DATA1到DATA5为例:,DS,随机 00 10 55 A4 00 30 00 00 00 00 20 01 40 02 60 03,DATA1 DATA2,DATA3,DATA4,DATA5,DS,54 48 49 53 20 49 53 20 41 20 45 58 41 4D 50 4C 45,例: DATA6 DB THIS IS A EXAMPLE,DATA6,T H I S I S A E X A M P L E,注意: 1:数据定义语句在存储器中占有相应的单元, 如上面语句中的第二句在程序运行时将会以00 和10占据两中存储单元。而EQU只是定义了一 个数据,在汇编后以实际数据的形式体现在程 序中。也就是说EQU语句不会占有存储单 元。 2:EQU可以用在指令中,而数据定义语句不可以。,二、表达式赋值语句,以上介绍了表达式中使用的各种运算符,如果一个表达式同时具有多个运算符,则按以下规则运算: 优先级高的先运算,优先级低的后运算。 优先级相同时按表达式中从左到右的顺序运算。 括号可以提高运算的优先级,括号内的运算总是在相邻的运算之前进行。,1. 赋值语句EQU,为了使程序便于阅读和修改,我们有时使用一个符号来代表一个数,而符号代表了一定的意义,在程序中使用一个符号代表一个数进行操作。 格式:符号 EQU 表达式,例如: PORT EQU 3F8H 在程序中可使用 MOV DX, PORT 对DX进行赋值,实际上PORT就是一个常量。,还可在语句中进行运算,如: DATA_PORT EQU 3F8H STAT_PORT EQU 3F8H+2 SEED EQU 10 FUNC EQU SEED*SEED+2*SEED+1,2=(等号) 格式: 名字=表达式 = (等号)伪指令的功能与EQU伪指令基本相同,主要区别在于它可以对同一个名字重复定义。 例如:,注意: 1:数据定义语句在存储器中占有相应的单元,如数据 定义语句中的DW 1000H在程序运行时将会以00和10 占据两中存储单元。而EQU只是定义了一个数据,在 汇编后以实际数据的形式体现在程序中。也就是说 EQU语句不会占有存储单元。 2:EQU可以用在指令中,而数据定义语句不可以。,3LABLE 格式:名字 LABLE 类型 LABLE伪指令的用途是定义标号或变量的类型。变量的类型可以是BYTE、WORD、DWORD等;标号的类型可以是NEAR或FAR。 利用LABEL伪指令可以使同一个数据区兼有BYTE和WORD两种属性,这样,在以后的程序中可根据不同的需要分别以字节或字为单位存取其中的数据。 例如:,LABEL伪指令也可以将一个属性已经定义为NEAR或者后面跟有冒号 (隐含属性为NEAR) 的标号再定义为FAR。例如: AGAINF LABEL FAR ;定义标号AGAINF的属性为FAR AGAIN: PUSH AX ;定义标号AGAIN的属性为NEAR 上面的过程既可以利用标号AGAIN在本段内被调用,也可以利用标号AGAINF被其他段调用。,三、段定义语句,段定义伪指令的用途是在汇编语言源程序中定义逻辑段。常用的段定义伪指令有SEGMENT/ENDS和ASSUME等 。 1SEGMENTENDS 格式: 段名 SEGMENT 定位类型 组合类型 类别 ;逻辑段内容 段名 ENDS,功能:将一个逻辑段定义成一个整体,段名逻辑段的标志符,不可省略,它确定了逻辑段在存储器中的地址,SEGMENT 和.ENDS前的段名必须相同。,SEGMENT ENDS段定义的伪指令助记符,任何一个逻辑段必须以SEGMENT开始,ENDS结束,不可省略,且必须成对出现,两者间为本逻辑段的内容。,定位类型(Align Type),定位类型参数是对该段起始地址定位。,* BYTE指定该段的起始地址定位在存储单元节的任何字节地址。,* WORD指定该段的起始地址定位在字的边界,即段的首地址必须是偶数。,* PAGE指定该段的起始地址定位在页的边界,即段的首地址必须是256的整倍数。,* PARA指定定位段的起始地址必须在节的整数边界,当定位类型参数缺省时,默认为PARA。,例: SEGMENT伪指令定义符的定位类型应用举例。 STACK SEGMENT STACK ;STACK段,定位类型缺省 DB 100 DUP(?) ;长度为100字节 STACK ENDS ;STACK段结束 DATA1 SEGMENT BYTE ;DATA1段,定位类型BYTE STRING DB This is an example! ;长度为19字节 DATA1 ENDS ;DTAT1段结束 DATA2 SEGMENT WORD ;DATA2段,定位类型WORD BUFFER DW 40 DUP(0) ;长度为40个字,即80字节,DATA2 ENDS ;DATA2段结束 CODE1 SEGMENT PAGE ;CODE1段,定位类型PAGE ;假设CODE2段长度为13字节 CODE1 ENDS ;CODE1段结束 CODE2 SEGMENT ;CODE2段,定位类型缺省 START: MOV AX,STACK MOV SS,AX ;假设CODE2段长度为52字节 CODE2 ENDS ;CODE2段结束 END START ;源程序结束,本例的源程序中共有五个逻辑段,它们的段名和定位类型分别如下: STACK段 PARA DATA1段 BYTE DATA2段 WORD CODE1段 PAGE CODE2段 PARA,已经知道其中STACK段的长度为100字节(64H),DATA1段的长度为19字节(13H),DATA2段的长度为40个字,即80字节(50H)。假设CODE1段占用13字节(0DH),CODE2段占用52字节(34H)。 如果将以上逻辑段进行汇编和连接,然后再来观察各逻辑段的目标代码或数据装入存储器的情况。由表5.3可清楚地看出,当SEGMENT伪指令的定位类型不同时,对段起始边界的规定也不相同。,上例各逻辑段的起始地址和结束地址,组合类型(Combine Type)各逻辑段之间的组合方式,* NONE该段与其它同名段不进行连接,各段独立存在与存储器中。 NONE可作为缺省参数。,* PUBLIC该段与其它模块中的同名段连接 时,由低地址到高地址连接起来,组成一个逻辑段。,* COMMON该段在连接时与其它模块中的同名段有相同的起始地址,采用覆盖的方式在存储器中存放,连接长度为各分段中最大长度。,* AT表达式定位该段的起始地址在表达式所指定的节(16的整倍数)边界上。,* STACK指定该段为堆栈段,不可缺省,多个模块只需设置一个堆栈段,各个模块中堆栈段采用覆盖方式组合。,* MEMORY定位该段与其它模块的的同名段有相同的首地址,采用覆盖的方式在存储器中组合连接。,分类名(Class Name),分类名必须用单引号括起来,分类名可选择49个字符的名称,用于汇编程序连接时将所有分类名相同的逻辑段组成一个段组。,例如,假设一个主程序中有五个逻辑段,段名和类别名分别为: STK1段 STACK CODE1段 无 DATA1段 BUFFER DATA2段 TABLE DATA3段 BUFFER,还有一个子程序,包括四个逻辑段,段名和类别名分别为:,DATA4段 TABLE DATA5段 BUFFER STK2段 STACK CODE2段 无,当将上述主程序和子程序进行连接时,两个程序模块中各逻辑段装入内存的顺序见下图。,逻辑段按类别装入内存的示意图,2. 段分配语句ASSUME,格式:ASSUME 段寄存器名:段名,段寄存器名:段名,,功能:定义四个逻辑段,指明段和段寄存器的关系。,ASSUME伪指令只指定某个段分配给哪个段寄存器,并将 代码段的段基址自动装入CS寄存器中,而不能自动把其它段 基址装入相应的段寄存器中,所以在代码段的开始要有一段 初始化程序完成这一工作。 对堆栈段来说,除了将段基址装入SS寄存器外,还要将 栈顶偏移地址置入堆栈指示器SP中。,例如: CODE SEGMENT ASSUME CS:CODE,DS:DATA1,SS:STACK MOV AX,DATA1 MOV DS,AX ;给DS赋值 MOV AX,STACK MOV SS,AX ;给SS赋值 CODE ENDS,注:可以用ASSUME NOTHING 取消前面由ASSUME所制定的 段寄存器。,例:求出两个16位数M1和M2的积 DATA_SEG SEGMENT M1 DW 0058H M2 DW 012AH M3 DW ? M4 DW ? DATA_SEG ENDS STACK_SEG SEGMENT S_DATA DB 100 DUP(?) TOP EQU LENGTH S_DATA STACK_SEG ENDS CODE_SEG SEGMENT ASSUME CS:CODE_SEG, DS:DATA_SEG, SS:STACK_SEG START: MOV AX, DATA_SEG MOV DS, AX MOV AX, STACK_SEG MOV SS, AX MOV AX, TOP MOV SP, AX,58 00 2A 01,DS,M1 M2 M3 M4,MOV BX, OFFSET M1 MOV AX, BX MOV BX, OFFSET M2 MUL BX MOV BX, OFFSET M3 MOV BX, AX MOV BX, OFFSET M4 MOV BX, DX MOV AH, 4CH INT 21H DOCE_SEG ENDS END START,从上述程序中,我们可总结出如下结论: SEGMENT和ENDS前面必须有标号,而且在相互配对的段,它们前面要使用相同的标号。对于不同的段定义标号,尽管这些标号可以是任意字串,但为了程序的可读性,应使其有一定的意义。 ASSUME语句可使汇编器知道CS、DS、SS指向哪个段,但它只在汇编时起作用,在运行时CPU并不知道除CS外的其它段地址,所以必须在程序中用指令进行赋值。 首条被执行的语句有一个标号,用以标出这个程序的开始执行处。 (在程序的结尾处使用END后跟这个标号)。,四、 过程定义语句 过程也就是子程序,所以过程定义伪指令也就是子程序定义伪指令。 格式: 过程名 PROC 属性 ;过程内容 RET N 过程名 ENDP,功能:定义一个过程,程序中其他地方就可以用CALL指令 调用这个过程,过程名实质上是过程入口的符号地址,它和标号一样,也有三种属性:段属性、偏移量属性和类型。过程的类型属性可以是NEAR或FAR。,RET N一般来说,被定义为过程的程序段中应该有返回指令RET,但不一定是最后一条指令,也可以有不止一条RET指令(在不同的条件下,从不同的出口返回)。执行RET指令后,控制返回到原来调用指令CALL的下一条指令。N为弹出值,可以缺省,N表示从过程返回后,堆栈中应有N个字节作废(以栈顶开始),N必须为正偶数。,过程和其它程序可定义在同一个段中,也可定义在不同的段中。对过程的调用要使用CALL语句,如: CALL PROC_NAME1 CALL PROC_NAME2 注:如果在过程定义中没有写明是NEAR过程或FAR过程,则汇编器将这个过程默认为NEAR过程。,例: 有一个过程PROG_N,其定义如下: PROG_N PROC NEAR RET PROG_N ENDP 则执行 CALL PROG_N 指令的过程可描述如下图。(设调用前:CS=2000H, IP=1050H, SS=5000H, SP=0100H, PROG_N与CALL指令之间的距离为1234H)。,2000:1050,2000:1053,5000:0100,5000:00FE,执行CALL PROG_N指令,执行RET指令,设在过程调用中需要三个字的参数,则可用下面的方法来传递参数。 调用程序: PUSH 参数1 PUSH 参数2 PUSH 参数3 CALL PROG_N 过程程序: PROG_N PROC NEAR MOV BP,SP ;BP=00F8H RET 6 PROG_N ENDP,用BP作指针来访问堆栈段,则可得到调用程序中所给的三个参数。,2000:1050,2000:1053,2000
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 音乐b级考试试题及答案
- 仪表培训考试试题及答案
- 六一周系列活动方案
- 六一外卖联动活动方案
- 六一教育教学活动方案
- 医学超声考试试题及答案
- 六一活动亲子diy活动方案
- 六一活动接球活动方案
- 六一活动评比活动方案
- 六一童装活动方案
- 中外石油文化智慧树知到期末考试答案2024年
- (正式版)JBT 14449-2024 起重机械焊接工艺评定
- MOOC 会计学-浙江工商大学 中国大学慕课答案
- GB/T 42791-2024航空用铝合金锻件通用技术规范
- 侵犯公民个人信息谅解书模板
- 国家电网培训课件
- 西安幸驾坡城改方案
- 2023年中考数学复习-拱桥问题(实际问题与二次函数)
- YY/T 0489-2023一次性使用无菌引流导管及辅助器械
- 不寐患者的护理查房
- 污水处理厂工程投标方案技术标
评论
0/150
提交评论