690 likes | 838 Vues
第5章 宏汇编语言. 5.1 汇编源程序的语句类型 一个完整的汇编程序至少应包含两类语句:一类是指令性语句;另一类是指示性语句。 指令性语句的书写格式如下: 标号: 符号指令;注释 变量名 伪 指 令;注释. 返回本章首页. LEA bx,buf abc: MOV al, 0 MOV dl,[bx] SUB al,dl CLC ROL al, 1 JZ rrr MOV NOT0,dl JMP qqq INC bx rrr: MOV minus,dl qqq: JMP abc. 指令语句的一般格式如下:
E N D
第5章宏汇编语言 5.1 汇编源程序的语句类型 一个完整的汇编程序至少应包含两类语句:一类是指令性语句;另一类是指示性语句。 指令性语句的书写格式如下: 标号: 符号指令;注释 变量名 伪 指 令;注释 返回本章首页
LEA bx,buf abc: MOV al,0 MOV dl,[bx] SUB al,dl CLC ROL al,1 JZ rrr MOV NOT0,dl JMP qqq INC bx rrr: MOV minus,dl qqq: JMP abc
指令语句的一般格式如下: • [标号:] 指令助记符 操作数 ;注释 • 1.标号:标号是机器指令语句存放地址的符号表示,代表该指令目标代码的第一个字节地址,后面必须紧跟冒号“:”。 • 2.指令助记符:指令助记符为语句的核心成分,表示了该语句的操作类型。 • 3.操作数:操作数表示指令助记符的操作对象。 • 4.注释:注释均以分号开始,它可占一行或多行,一般放在一条语句的后面。 返回本节
伪指令语句格式 • 伪指令语句格式如下: • [符号名] 伪指令符 操作数 ;注释 • 1.符号名:符号名是伪指令语句的一个可选项。 • 2.伪指令符:伪指令符指定汇编程序要完成的具体操作,如数据定义伪指令DB、DW、DD,段定义伪指令SEGMENT,假定伪指令ASSUME等。 • 3.操作数:伪指令后面的操作数可以是常数、字符串、变量、表达式等,其个数由具体的伪指令决定,各个操作数之间必须以“逗号”分隔。 • 4.注释:伪指令的注释必须以“;”开始,其作用同指令语句中的注释部分。 返回本节
5.2 宏汇编基本语法 5.2.1 标号、变量和常数 1 标号和变量:命名规则、属性(段属性、偏移属性、类型属性) 2 常量:立即数,字符串常数,符号常数(定义) 5.2.2 运算符 1 数值运算符 (1)算术运算符(+、-、*、/、MOD ) (2)逻辑运算符(NOT、AND、OR、XOR、HIGH、LOW) (3)关系运算符(EQ、NE、GT、LT、GE、LE)值的确定 2 修改属性的运算符 PTR 3 返回属性或数值的运算符 (1)SEG运算符 (2)OFFSET运算符 返回本章首页
(3)TYPE运算符(功能) (4)$运算符(功能) 4 方括号运算符和地址表达式 5.3 数据定义伪指令 1 等值伪指令(EQU) 2 等号伪指令(=)两者的差别 3 字节定义伪指令 4 字定义伪指令 5 双字定义伪指令 6 多字节定义伪指令
5.4 宏汇编语言基本语句 • 一个完整的汇编语言源程序结构上的要求: • 用方式选择伪指令说明执行该程序的CPU类型 • 用段定义伪指令定义每一个逻辑段 • 用过程定义伪指令定义每一个子程序 • 用ASSUME语句说明段的约定 • 用汇编结束语句说明源程序结束 • 程序在预定功能结束后,返回DOS系统。
1 方式选择伪指令(通常作为整个程序的第一个语句,可以缺省) 2 段定义伪指令 3 段约定语句 4 过程定义语句 5 定位语句 6 汇编结束语句
字符串常量 • 字符串常量是用单引号或双引号引起来的一个或多个字符。字符串常量是以各字符的ASCⅡ码表示的。如‘A’用41H 表示,字符串‘A1B2’用41H,31H,42H,32H表示。 返回本节
变量 • 1.变量 • 2.变量的定义
1.变量 • (1)段属性 • (2)偏移地址属性 • (3)类型属性
2.变量的定义 • 表达式项是给变量或指定存储单元赋予初值,它有以下几种形式: • (1)数值表达式 • (2) 字符串表达式 • (3)地址表达式(只适用DW和DD两个伪指令) • (4)? 表达式 • (5)带DUP的表达式
(1)数值表达式 • 数据定义伪指令可以为一个或连续的存储单元设置数值初值。 • 【例3.1】为数据段分配存储单元。 • DATA SEGMENT • A DB 11H,12H,13H • B DW 1122H,3344H • C DD 12345678H • DATA ENDS • 上述变量的存储单元分配及初始化情况如下图3.1所示。
(2) 字符串表达式 • 字符串表达式中的字符串必须用引号引起来。DB、DW、DD伪指令将字符串中的各字符均以ASCⅡ码形式存放在相应的存储单元,但表示形式各不相同。 • 【例3.2】为字符串分配存储单元。 • DATA SEGMENT • STR1 DB ‘1234’ • STR2 DW ‘AB’,‘CD’,‘A’ • STR3 DD ‘AB’ • DATA ENDS • 其存储单元分配如下图3.2所示。
(3)地址表达式(只适用DW和DD两个伪指令) • 如果该地址表达式为一变量(或标号)名,用DW伪指令则是取它的偏移地址来初始化变量,用DD伪指令则是取它的段首址和偏移地址来初始化变量。 • 例如: • BUF1 DW A • BUF2 DD B
(5)带DUP的表达式 • 在表达式中使用重复数据操作符DUP,可以为连续的存储单元提供重复数据,其格式为: • N DUP(表达式) • 其中N为重复因子,只能取正整数,表示定义了N个重复数据存储单元,其类型由它前面的数据定义伪指令确定,而每个数据存储单元中的初值由DUP后面圆括号中的表达式给定。 • 例如: BUF DB 100 DUP(0) • 以上语句定义了以BUF为首址,大小为100个字节,初值为0的数据存储单元。 返回本节
标号 • 标号是一条指令语句的符号地址。在汇编源程序中,只有在需要转向一条指令语句时,才为该指令语句设置标号,以便在转移类指令(含子程序调用指令)中直接引用这个标号。因此,标号可作为转移类指令的操作数,即转移地址。 • 【例3.3】符号地址表示。 • ┆ • NEXT:MOV AL, [SI] ;带标号NEXT的指令 • ┆ • DEC CX • JNE NEXT ;标号NEXT作转移指令的操作数
标号也具有三种属性 • 1.段属性 • 2.偏移地址属性 • 3.类型属性 返回本节
4 表达式 • 1.操作数 • 2. 算术运算符 • 3.逻辑运算符 • 4.关系运算符 • 5.属性运算符 • 6.数值返回运算符
1.操作数 • 算术运算符包括:+(加)、-(减)、*(乘)、/(除)、MOD(求模)、SHL(左移)、SHR(右移)几种,它既可以用于数值表达式又可用于地址表达式。 2.算术运算符
【例3.4】用算术运算符进行数值表达式运算。 • ┆ • NUM1 EQU 25*4 –50 ;NUM1=50 • NUM2 EQU NUM1 / 7 ;NUM2=7 • NUM3 DB NUM1 MOD 7 ;NUM3=1 • VAR1 DB 1,2,3,4,5 • VAR2 DB ‘12345’ • NUM4 EQU VAR2-VAR1 ;NUM4=5 • NUM5 EQU 0FH • ┆ • MOV AL,NUM5 SHL 4;(AL)=11110000B • MOV BL,NUM5 SHR 4;(BL)=00000000B
3.逻辑运算符 • 逻辑运算符包括:逻辑乘(AND)、逻辑加(OR)、按位加(XOR)、逻辑非(NOT)四种运算。由于逻辑运算是按位操作,且在汇编过程中完成,因而运算的结果仍为整数常量。 • 【例3.5】用逻辑运算符进行运算。 • MOV AL,34H AND 0FH ;04H→AL • MOV BL,05H OR 30H ;35H→BL • MOV CX,NOT 00FFH ;0FF00H→CX • MOV DX,789AH XOR 000FH ;7895H→DX
4.关系运算符 • 关系运算符包括:相等(EQ),不等(NE),小于(LT),大于(GT),小于等于(LE)及大于等于(GE)。 • 【例3.6】用关系运算符进行数值表达式运算。 • NUM1 DB 10 LT 5 ;NUM1=0 • NUM2 DB 0AAAAH GT 7FFFH ;NUM2=0FFFFH • MOV AX,‘A‘ EQ 41H ;0FFFFH→AX • MOV BX,NUM2 LT NUM1 ;0→BX
5.属性运算符 • (1)PTR运算符 • 格式: 类型 PTR 地址表达式 • ② PTR与EQU连用,可定义与PTR右边地址表达式类型不同的新变量名或新标号,但不另分配存储单元。
6.数值返回运算符 • (1)SEG 运算符 • (2)OFFSET运算符 • (3)TYPE运算符 • (4)SIZE运算符 • (5)字节分离运算符
(1)SEG 运算符 • 格式:SEG 变量或标号 • 功能:分离出其后变量或标号所在段的段首址。例如: • MOV AX,SEG ARR • MOV DS,AX • (2)OFFSET运算符 • 格式:OFFSET 变量或标号 • 功能:分离出其后变量或标号的偏移地址。例如: • MOV BX,OFFSET BUF
(3)TYPE运算符 • 格式:TYPE 变量或标号 • 功能:分离出其后变量或标号的类型。如果是变量,将返回该变量的类型对应字节数;如果是标号,则返回代表标号类型的数值。它们之间的关系见表3.2所示。
(4)SIZE运算符 • 格式:SIZE 变量 • 功能:取出变量所含的数据存储区大小。其返回值为: • LENGTH 变量 * TYPE 变量 • 例如:上例中A、B、C三变量: • SIZE A = LENGTH A*TYPE A = 1 • SIZE B = LENGTH B*TYPE B = 20 • SIZE C = LENGTH C*TYPE C = 1
(5)字节分离运算符 • 字节分离运算符包括:HIGH和LOW。 • 格式:HIGH 常量或地址表达式 • LOW 常量或地址表达式 • 功能:HIGH 用来分离出其后16位常量或地址表达式的偏移量的高字节; • LOW用来分离出其后16位常量或地址表达式偏移量的低字节。 返回本节
5.4 宏汇编语言基本语句 1 方式选择伪指令 (1).8086 ;只汇编8086、8088指令 (2) .286或.286C ;只汇编8086、8088及80286实模式指令 (3).286P ;只汇编8086、8088及80286全部指令 (4).386或.386C ;同 .286,且汇编80386实模式指令 (5).386P ;同.286P,且汇编80386全部指令 (6).486或. 486C ;同.386,且汇编80486实模式指令 (7) .486P ;同.386P,且汇编80486全部指令。 返回本章首页
数据定义伪指令 常用的数据定义伪指令有DB,DW,DD,DQ,DT。 格式:[变量名] 数据定义伪指令 表达式 [,…] 功能:定义数据存储区,类型由数据定义伪指令确定,初值由表达式给定。 返回本节
符号定义伪指令 • 1.等价伪指令 • 2.等号伪指令 • 3.定义符号名伪指令
1.等价伪指令 • 格式:符号名 EQU 表达式 • 功能:为常量、表达式及其他各种符号定义一个等价的符号名,但它不申请存储单元。 • 用途:① 用符号表示常量、数值表达式,即定义符号常量。使用符号常量可使程序简单明了,增强程序的可读性和通用性。 • ② EQU与属性运算符PTR或THIS联合使用,可以给变量或标号定义新的类型属性并重新命名,但保持其段偏移地址属性不变。 • ③ 利用EQU可以用一个符号名替代一个复杂的地址表达式和其他一些符号,如指令助记符、变量名、标号、段名、寄存器名、宏定义名等。
2.等号伪指令 • 格式:符号名 = 表达式 • 功能:为常量、表达式及其他各种符号定义一个等价的符号名,并能对所定义的符号多次重复定义,且以最后一次定义的值为准。 • 【例3.17】定义等价符号名。 • ┆ • COST = 20 • M = MOV • LOST = LOST+10 ;30→LOST • M = ADD ;M=ADD • ┆
3 段定义伪指令SEGMENT/ENDS 段名 SEGMENT 定位参数 连接参数 ‘分类名’ 段长度 段体 段名 ENDS • 1.定位参数 • 2.连接参数 • 3.分类名 • 4.段长度
1.定位参数 • (1)PARA:表示本段必须从能被16整除的地址处开始存放,即段起始地址最低四位必须是0。 • (2)WORD:表示本段要从一个偶数地址处开始存放,即段起始地址的最低一位必须是0。 • (3)BYTE:表示本段起始地址可以从任一地址处开始存放。 • (4)PAGE:表示本段要从能被256整除的地址处开始存放,即起始地址的最低八位必须是0。
【例3.19】对连接程序进行连接后存储区各段相对位置分布。【例3.19】对连接程序进行连接后存储区各段相对位置分布。 DATA1 SEGMENT ‘DATA’ CODE SEGMENT ‘CODE’ STACK1 SEGMENT ‘STACK’ DATA2 SEGMENT ‘DATA’ STACK2 SEGMENT ‘STACK’ 经连接程序连接后,各段的相对位置如下: DATA1 SEGMENT ‘DATA’ DATA2 SEGMENT ‘DATA’ STACK1 SEGMENT ‘STACK’ STACK2 SEGMENT ‘STACK’ CODE SEGMENT ‘CODE’
2.链接参数 • 组合方式有六种类型可供选择。 • (1)缺省:表明该段是一个独立的逻辑段,链接程序对于不同模块中,链接参数缺省的同名段,不进行组合。 • (2)PUBLIC :把不同模块中具有PUBLIC属性的同名段,在满足定位方式的前提下,按照指定的链接顺序进行链接。 • (3)STACK :链接程序将把不同模块中具有STACK属性的同名段链接成一个大的堆栈段。连接后的堆栈空间是链接前后模块预留的堆栈空间之和。 • (4)COMMON :把不同模块中具有COMMON属性的同名段,根据指定的链接顺序,按照“覆盖”方式组合成一个逻辑段。组合之后的逻辑段空间,等于链接之前具有COMMON属性同名段中最大的段体 • (5)MEMORY :等价于PUBLIC • (6)AT表达式 :逻辑段在定位时,其段基址等于表达式给出的值。AT不能在代码段中使用。
【例3.20】有两个模块,各模块段定义如下: • 模块1: • ┆ DATA1 SEGMENT PARA PUBLIC ‘DATA1’ M1 DB 45H DUP(0) DATA1 ENDS DATA2 SEGMENT PARA COMMON ‘DATA2’ N1 DB 102H DUP(0) DATA2 ENDS END
模块2: • ┆ DATA1 SEGMENT PARA PUBLIC ‘DATA1’ M2 DB 104H DUP(11H) DATA1 ENDS DATA2 SEGMENT PARA COMMON ‘DATA2’ N2 DB 105H DUP(0) DATA2 ENDS DATA3 SEGMENT T1 DB 50 DUP(20H) DATA3 ENDS END
该段的定位组合方式示意图如图3.3所示。 图3.3 模块1、模块2连接后段的定位组合方式示意图 返回本节
3 分类名:表示逻辑段的类别,长度不超过40个字符,必须用单引号括起来。 4 段长度:是386、486新增的段参数 (1)USE16 (2)USE32
5 假定伪指令ASSUME • 格式:ASSUME 段寄存器:段名 [,段寄存器:段名] • 功能:建立段寄存器与段之间的对应关系。该伪指令一般出现在代码段中。 • 【例3.21】用ASSUME伪指令建立代码段、堆栈段与CS和SS的对应关系。 • DATA1 SEGMENT • A DB 1,2,3 • DATA1 ENDS • STACK SEGMENT STACK • DB 200 DUP(0) • STACK ENDS • DATA2 SGEMENT • B DB ‘123ABC
DATA2 ENDS • DATA3 SEGMENT • C DB ?,?,? • DATA3 ENDS • CODE SEGMENT ASSUME DS:DATA1,ES:DATA2,CS:CODE,SS:STACK • START: MOV AX,DATA1 • MOV DS,AX ;DATA1→DS • MOV AX,DATA3 • MOV ES,AX ;DATA3→ES • ┆
Q1: MOV AL,A • Q2: MOV C,AL • ASSUME DS:DATA2 ;建立DS与B段的对应关系 • MOV AX,DATA2 • MOV DS,AX • MOV AL,B • MOV C,AL • ┆ • CODE ENDS • END START 返回本节
6 置汇编地址计数器伪指令ORG • 格式:ORG 数值表达式 • 功能:将数值表达式的值赋给汇编地址计数器。数值表达式的值须为0~65535之间的非负整数。 • 【例3.22】给汇编地址计数器赋值。 • DATA SEGMENT • ORG 10 ; 置$值为10 • VAR1 DW 100H,200H • ORG $+5;置$的值为14+5,即为19 • VAR2 DB 1,2, $+1,$+2 • N EQU $-VAR2;($)=23 • DATA ENDS 返回本节
7 源程序结束伪指令 • 格式:END [表达式] • 功能:该语句标志整个程序的结束,是源程序的最后一条语句。 返回本节
9 过程定义伪指令PROC,ENDP,NEAR,FAR 10 定义结构的伪指令STRUC/ENDS 11 条件汇编伪指令 12 逻辑运算伪指令 13 访问外部标识伪指令 格式:EXTRN 标识符:类型,… PUBLIC 标识符,… EXTRN语句中的标识符标识符表示外部的变量或标号 PUBLIC指令中的标识符表示可供其它模块引用的变量或标号