汇编语言程序格式

不同的汇编程序由不同的汇编语言编程规定。目前支持Intel 8086/8088系列微机,常用的汇编程序有ASM、MASM、TASM、OPTASM等。

汇编语言语句种类及其格式

汇编语言的语句可以分为指令语句和伪指令语句

指令语句
每一条指令语句在汇编时都要产生一个可供cpu执行的机器目标代码,它又叫可执行语句。

指令语句的一般格式为:
标号: 指令助记符 操作数; 注释

标号是可选字段,它后面必须有冒号:。标号是一条指令的符号地址,代表了该指令的第一个字节存放地址。
标号一般放在一个程序段或子程序的入口处,控制程序的执行转到该程序的位置。

在转移指令或子程序调用指令值,可直接引用这个标号。

指令助记符字段
该字段是一条指令的必选项,它表示这条语句要求cpu完成什么具体操作。

有些指令还可以在指令助记符的前面加上前缀,实现一定的附加操作。

操作数字段
一条指令可以有一个,两个或者无操作数

注释字段为可选项,该字段以分号;开始

伪指令语句

伪指令语句又叫命令语句
伪指令本身不产生对应的机器目标代码,它仅仅是告诉汇编程序对其后面的指令语句和伪指令语句的操作数应该如何处理

一条伪指令语句可以包含四个字段

符号名 伪指令符 操作数; 注释

标识符
指令语句中的标号和伪指令语句中的符号名统称为标识符。标识符是由若干的字符构成的。
标识符的构成规则:
字符的个数是1-31个
第一个字符必须是字母、问号、@或下下划线_这4种字符
不能使用系统专用的保留字


汇编语言数据
数据是指令和伪指令语句中操作数的基本组成部分,一个数据是由数值和属性两部分组成。
在说明数据时不仅要指定其数值,还需要说明它的属性,比如是字节数据还是字数据
在汇编语言中常用的数据形式有:常数、变量和标号

常数
常数在汇编期间其值已经完全确定,并且在程序运行过程中,其值不会发生变化

常数有以下几种形式:
二进制数 以字母B结尾
八进制数 以字母O或者Q结尾
十进制数 以字母D结尾,或者没有字母结尾
十六进制数 以字母H结尾 如果常数的第一个数字为字母,为了 与标识符加以区别,必须在其前面加上数字0

实数 一般格式:
整数部分.小数部分E+指数部分
汇编程序在汇编程序时,可以把实数转换成4字节、8字节或10字节的二进制数形式存放

字符串常数:用引号(单引号或者双引号)括起来的一个或者多个字符,这些字符在内存中以它的ASCII码植存储在内存中。

可以作为指令语句的源操作数
在指令语句中的直接寻址方式、变址寻址方式或基址变址寻址方式中作为位移量
在数据定义伪指令中使用

变量
变量用来表示存放数据的存储单元,这些数据在程序运行期间可以被改变
程序中以变量名的形式来访问变量,因此,可以认为变量名就是存放数据的的存储单元的地址

变量的定义与预置
定义变量就是给变量在内存中分配一定的存储单元。也就是给这个存储单元赋予一个符号名,即变量名,同事还要讲这些存储单元预置初值
定义变量使用数据定义伪指令

DB 定义字节变量
DW 定义字变量
DD 定义4字节变量
DQ 定义8字节变量
DT 定义10字节变量
变量定义的一般格式为:
变量名 数据定义伪指令 表达式1,表达式2
其中表达式1、表达式2是给存储单元赋的初值

当变量被定义后,就具有以下三个属性:
段属性
它表示变量存放在哪一个逻辑段中
偏移量属性
它表示变量所在的位置与段起始点之间的字节数
段属性和偏移量属性就构成了变量的逻辑地址
类型属性
它表示变量占用的存储单元的字节数

在变量定义中,给变量赋初值的表达式可以使用下面4种形式:

数值表达式
? 表达式
问号?表示可以预置任意内容
字符串表达式
对于DB伪指令,字符串为用引号括起来的不超过255个字符。给每一个字符分配一个字节单元。字符串按从左到右,将字符的ASCII编码值以地址递增的排列顺序依次存放

DUP表达式
DUP称为重复数据操作符
使用DUP表达式的一般格式为:
变量名 数据定义伪指令 表达式1 DUP(表达式2)
其中:表达式1是重复的次数,表达式2是重复的内容
DUP还可以嵌套使用,即表达式2又可以使一个带DUP的表达式。

变量的使用
在指令语句中引用
在指令语句中直接引用变量名就是对其存储单元的内容进行存取

当变量出现在变址寻址或基址变址寻址的操作数中时表示取用该变量的偏移量

在伪指令语句中引用
它表示取变量地址的偏移量
DD 取变量段基值和偏移量。前两个字节存偏移量,后两个字节存段基值

#### 标号
标号写在一条指令的前面,它就是该指令在内存中的存放地址的符号表示,也就是指令地址的别名。
标号主要用在程序需要改变程序的执行顺序时,用来标记转移的目的地,即作转移至零的操作数

每个标号具有三属性
###### 段属性
它表示该标号所代表的地址在哪个逻辑段中,即段基值
###### 偏移量属性
它表示该标号所代表的地址在段内与段起点间的字节数,即地址的偏移量
###### 距离属性(也叫类型属性)
它表示该标号可以被段内还是段间的指令调用
NEAR():该标号只能作段内转移,也就是说只能是与该标号所指指令同在一个逻辑段的转移指令和调用指令才能使用它。
FAR:该标号可以被非本段的转移和调用指令使用。

标号的距离属性可以有两种方法来指定:
隐含方式:
当标号加在指令语句前面时,它隐含为NEAR属性。
用LABEL伪指令给标号指令距离属性
格式:标号 LABEL 类型

SUB_FAR LABEL FAR
SUB1: MOV AX, 30H

SUB1_FAR与SUB1两个标号具有相同的段属性和偏移量属性,即相同的逻辑地址。被转移指令或调用指令访问时,是指同一个入口地址,但SUB1_FAR可以被其他段的指令调用

LABEL伪指令还可以用来定义变量的属性,即改变一个变量的属性,如把字变量的高低字节作为字节变量来处理
DATA_BYTE LABEL BYTE
DATA_WORD DW 20H DUP(?)
DATA_BYTE与DATA_WORD具有相同的段基值和偏移量。DATA_BYTE可以被用来存取一个字节数据,而DATA_WORD则不能。

## 符号定义语句
在源程序设计中,使用符号定义语句可以将常数或表达式等内容用某个指定的符号来表示。在8086/8088汇编语言中有两种符号定义语句。

#### 等值语句
语句格式:符号名 EQU 表达式
功能:用符号名来表示EQU右边的表达式,后面的程序中一旦出现该符号名,汇编程序将把它替换成该表达式

表达式可以是任何形式,常见的有以下几种情况。
##### 常数或数值表达式
COUNT EQU 5
NUM EQU COUNT + 5

##### 地址表达式
ADR1 EQU DS:[BP+14]
ADR1被定义为在DS数据段中以BP作基址寻址的一个存储单元

##### 变量、寄存器名或指令助记符
CREG EQU CS; 在后面的程序中使用CREG就是使用CX

注意在同一个源程序中,同一符号不能用EQU定义多次

#### 等号语句
格式:符号名=表达式
等号语句与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义

等值语句与等号语句都不会为符号分配存储单元。因此所定义的符号没有段、偏移量和类型等属性。

## 表达式与运算符
表达式是指令或伪指令语句操作数的常见形式。它由常数、变量、标号等通过操作运算符连接而成

任何表达式的植在程序被汇编的过程中 进行计算确定,而不是到程序运行时才计算

移位运算符和移位指令区别。移位运算符的操作对象是某一个具体的数(常数),在汇编时完成移位操作。而移位指令是对一个寄存器或存储单元内容在程序运行时执行移位操作。

下标运算符[]具有相加的作用
一般使用格式:
表达式1[表达式2]
作用:将表达式1与表达式2的值相加后形成一个存储器操作数的地址

逻辑运算符
逻辑运算符有notandor、和xor等四个,它们执行都是按位逻辑运算

关系运算符
eq等于、ne不等于、lt小于、gt大于、le小于等于、ge大于等于

关系运算符用来比较两个表达式的大小。关系运算符比较的两个表达式必须同为常数或同一逻辑段中的变量

如果是常量的比较,则按照无符号数进行比较;如果是变量的比较,则比较它们的偏移量大小。

关系运算的结果只能是真(1)或假(0)

数值返回运算符
该类运算符有5个,它们将变量或标号的某些特征值或存储单元地址的一部分提取出来。

seg运算符
作用:取变量或标号所在段的段基值
offset运算符
作用:该取变量或标号在段内的偏移量
type运算符
作用:取变量或标号的类型属性,并用数字形式表示。对变量来说就是取它的字节长度
length运算符
作用:取变量的长度
如果变量是用重复数据操作符dup说明的,则length运算符取外层dup给定的值。
如果没有用dup说明,则length运算返回值总是1
size运算符
作用:只能作用于变量,size取值是legnth和type两个运算符返回值的乘积

属性修改运算符
这一类运算符用来对变量、标号或者存储其操作数的类型属性进行修改或指定

PTR运算符
格式:类型 PTR地址 地址表达式
作用:将地址表达式所指定的符号、变量或用其他形式表示的存储器地址的类型属性修改为"类型"所指定的值

类型可以使byte、word、dword、near和far。这种修改是临时的,只在含有该运算符的语句内有效

high/low运算符
格式:
high 表达式
low 表达式

这两个运算符用来将表达式的值分离出高字节和低字节 
如果表达式为一个常量,则将其分离成高8位和低8位
如果表达式是一个地址(段基值或偏移量)时,则分离出它们的高字节和低字节
注意:high/low运算符不能用来分离一个变量、寄存器或存储器单元的高字节与低字节

this运算符
this运算符一般与等值运算符equ连用,用来定义一个变量或标号的类型属性。所定义的变量或标号的段基值和偏移量与紧跟其后的变量或标号相同

lfar equ this far
lnear: mov ax, B

标号lfar与lnear具有相同的逻辑地址值,但类型不同。lnear只能被本段中的指令调用,而lfar可以被其他段的指令调用

运算符的优先级

在一个表达式中如果存在多个运算符时。在计算时就有先后顺序问题。不同的运算符具有不同的运算优先级别

程序的段结构
8086/8088在管理内存时,按照逻辑段进行划分,不同的逻辑段可以用来存放不同目的的数据。在程序中使用段寄存器cs,ds,es,ss来访问它们

在源程序设计中,使用伪指令来定义和使用这些逻辑段

段定义的伪指令
伪指令segment和ends用于定义一个逻辑段。使用时必须配对,分别用于定义的开始与结束。

一般格式:
段名 segment [定位类型][组合类型]['类型名']
本段语句
段名 ends

段名
段名是由用户自己任意选定的,复合标识符定义规则的一个名称。
最好选用与该逻辑段用途相关的名称。如第一个数据段为data1,第二个数据段为data2等
一个段的开始于结尾用的段名必须一致

定位类型

定位类型用于决定段的起始边界,即第一个可存放数据的位置(不是段基址)。它可以有4种取值。
page:表示该段从一个页面的边界开始
由于一个页面为256个字节,并且页面编号从0开始,因此,page定位类型的起始地址的最后8位二进制数一定为0,即以00H结尾的地址

para:表示该段从一个小节的边界开始
如果用户未选定位类型,则缺省为para

word:表示该段从一个偶数字节地址开始,即段起始单元地址的最后一位二进制数一定是0

byte:表示该段起始单元地址可以是任一地址值
注意:定位类型为page和para时,段起始地址与段基址相同。定位类型为word和byte时,段起始地址与段基址可能不同

组合类型
组合类型说明符用来指定段与段之间的连接关系和定位。它有6种取值选择

若未指定组合类型,表示本段与其他段无连接关系。在装入内存时,本段有自己的物理段,因此有自己的段基址
public:在满足定位类型的前提下,将与该段同名的段领接在一起,形成一个新的逻辑段,公用一个段基址。段内的所有偏移量调整为相对于新逻辑段的段基址
common:产生一个覆盖段,在多个模块连接时,把该段与其它也用common说明的同名段置成相同的段基址,这样可达到共享同一存储区。共享存储区的长度由同名段中的最大段确定
stack:把所有的同名段连接成一个连续段,且系统自动对ss段寄存器初始化为该连续段的段基址,并初始化堆栈指针sp
at表达式:表示本段可定位在表达式所指示的小节边界上。表达式值也就是段基址
memory:表示本段在存储中应定位在所有其他段之后的最高地址上。如果有多个用memory说明的段,则只处理第一个用memory说明的段,其余的被视为common

类别名
类别名为某一个段或几个相同类型段设定的类型名称。系统在进行连接处理时,把类别名相同的段存放在相邻的存储区。但段的划分与使用仍按照原来的设定

类别名必须用单引号引起来。所用字符串可任意选定,但它不能使用程序中的标号、变量名字或其他定义的符号。
在定义一个段时,段名是必须有的项,而定位类型、组合类型和类别名三个参数是可选的。各个参数之间用空格分隔。各参数之间的顺序不能改变

如果在段定义中选用了para定位类型说明,则在一个段的结尾与另一个段的开始之间可能存在一些空白
在进行程序设计时,如果程序不大,一般只需要定义三个段即可

段寻址伪指令
段寻址伪指令assume的作用是告诉汇编程序,在处理源程序时,定义的段与哪个寄存器关联。

assume并不设置各个寄存器的具体内容,段寄存器的值在程序运行时设定
格式:
assume 段寄存器名:段名,段寄存器:段名
其中段寄存器名为cs,ds,es,ss四个之一,段名使用segment/ends伪指令定义的段名

在一个代码段中可以有几条assume伪指令,对于前面的设置,可以用assume改变原来的设置

一条assume语句不一定设置全部段寄存器,可以选择其中一个或几个段寄存器
可以使用关键字nothing将前面的设置删除

assume es:nothing:删除前面对es与某个定一段的关联
assume nothing 删除全部4个段寄存器的设置

过程定义伪指令
在程序设计过程中,常常将具有一定功能的程序段设计成一个子程序。在MASM宏汇编程序中,用过程proc/endp来构造子程序
过程定义伪指令格式如下:
过程名 proc [near/far]
    ...
    ret
过程名 endp

过程名是子程序的名称,它被用作过程调用指令call的母的操作数。它雷同一个标号的作用。具有段、偏移量和距离三个属性。而距离属性使用near和far来指定,若没有指定,则隐含为near
每一个过程必须包含有返回指令ret,其作用是控制cpu从子程序中返回到调用该过程的主程序

当前位置计数器$与定位伪指令org

汇编程序在汇编源程序时,每遇到一个逻辑段,就要为其设置一个位置计数器,它用来记录该逻辑段中定义的每一个数据或每一条指令在逻辑段中的相对位置

位置计数器$在使用上完全类似变量的使用

定位伪指令org--用来改变位置计数器的值
格式:
org 数值表达式
将数值表达式的值赋给当前位置计数器$,org语句为其后的数据或指令设置起始偏移量

发布了212 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43833642/article/details/104262311