目录
汇编程序除指令语句外,还需要提供一些指令,用于辅助源程序的汇编,比如指定程序或数据存放的起始地址,给数据分配一段连续的内存单元等,这些指令在汇编时不影响程序执行,因此称之为伪指令。
伪指令基本数据
1.标识符
必须由字母,数字,及特殊符号(_、$、?、@)组成,且必须由字母开头,不能以数字开头。
默认情况下,不区分字母大小写。
一个源程序中,每个标识符的定义是唯一的,不能是保留字(系统内置的)。保留字主要有:指令助记符(MOV、ADD),伪指令助记符(DB、segment),操作符(OFFSE、PTR),寄存器名(AX、CS)。
2.常数
常数分数字常数和字符串常数
数字常数可以是二进制(B)、八进制(Q)、十进制(D或不跟字母)、十六进制(H),数字常数的第一位必须是数字(可以加0表示一下)
字符串常数最长是255,要用单引号‘’括起来,这些用单引号‘’括起来的字符串常数在内存单元中都是以ASCII码来表示的。
3.变量名
存储单元的标识符(自定义名字),即与某一数据第一字节相对应的标识符(自定义名字)。
变量的三个属性:
段地址SEG ;变量所在段的段地址
偏移地址OFFSET ;变量所在段的偏移地址
类型TYPE ;变量的类型是所定义的每个变量所占据的字节数
变量的类型:
DB ;字节的意思,用于在存储单元中分配一个或多个字节单元,8位数据,0~255无符号数范围,-128~+127有符号数范围,还可以是字符串常数。
DW ;字的意思,用于在存储单元中分配一个或多个字单元,16位数据,0~65535无符号数范围,-32768~+32767有符号数范围
DD ;双字的意思,用于在存储单元中分配一个或多个双字单元,32位数据。
DQ ;四字
DT ;十个字节
4.标号
用标识符来表示地址,可用作转移指令和调用指令的目的操作数dest,以确定程序转移的目的地址
标号的三个属性:
段地址SEG ;与标号对应的指令首字节所在段的段地址
偏移地址OFFSET ;与标号对应的指令首字节所在段内的偏移地址
类型TYPE ;NEAR表示标号是近标号只能在段内引用,FAR表示标号是远标号可以在段间引用
伪指令数据定义
指令格式:变量名 助记符 操作数 ;注释
(1)变量名:是一个用标识符表示的符号地址,也可以省略,其值等于操作数第一个字节的偏移地址
(2)助记符:有DB、DW、DD、DQ和DT指令,如DB定义字节数据以及字符串,规定每个操作数占用一个字符,字符串的每个字母(ASCII)也是占用一个字符
(3)操作数:可以是常数,变量,表达式,字符串,?(不确定的数),标号。
(4)功能:从变量名指定的存储单元开始存放各操作数(操作数1...2...n),如果不需要存放任何操作数,则起到分配存储单元的作用。
(5)注释:用“;”分隔,“;”以后的内容为注释内容,只增加源程序的可读性,在汇编时,不对注释做任何处理。
(6)第一个变量是从0地址开始的,ORG可以控制变量的初始地址,如 ORG 100H,将从100H处安排数据或程序
伪指令符号定义
符号定义伪指令可以用来给表达式进行赋值,表达式可以是变量、常量、标号、数据表达式、地址表达式等,有两条伪指令可以实现符号定义,该类指令均不占用内存。
1.表达式赋值伪指令EQU
指令格式:符号名 EQU 数值
例:PI EQU 3.1415 ;将常数3.1415赋值给PI
COUNT EQU LENGTH+1 ;将 LENGTH+1 赋值给COUNT
2.等号伪指令”=“
指令格式:标识符=操作数
与EQU类似,但是EQU不允许一个标识符重复定义,而”=“允许一个标识符重复定义
例:EMP=6,EMP=9,EMP=EMP+1
伪指令段定义
1.段定义伪指令的组成
(1)可以包含多个代码段、数据段、附加段和堆栈段。
(2)必须包含一个代码段、并确定执行的起始点、一个程序只有一个起始点。
(3)所有的汇编指令必须位于代码段内。
(4)利用SEGMENT和ENDS伪指令定义逻辑段
(5)配合ASSUME伪指令指明哪些是逻辑段、代码段、堆栈段、数据段、附加段。
2.段结构定义
指令格式:
段名 SEGMENT 定位类型 组合类型 ‘分类名’
。。。
。。。(逻辑段内容)
段名 ends
(1)段名:给每一个逻辑段指定一个自定义的名字,段名的命名规则和变量的命名规则一样。
(2)SEGMENT和ENDS:是一对段定义语句,一个逻辑段从SEGMENT语句开始,到ENDS语句结束。
(3)定位类型的参数(可省略,默认为PARA)
PARA 规定20位的段起始地址为XXXXB
BYTE 规定20位的段起始地址定位在存储单元的任何字节地址
WORD 规定20位段起始地址定位在字的边界,即段的首地址是偶数
PAGE 规定20位的段起始地址为XXXB
(4)组合类型的参数(可省略,默认为NONE)
NONE 该段与其它同名段不连接,独立存在于存储器中
PUBLIC 规定该段与其他模块中的同名段在满足定位类型的前提下依次由低地址到高地址连接起来,连接顺序由LINK软件确定
COMMON 规定该段与其他模块中的同名段有相同的起始地址,采用覆盖的方式存放,公共存储区的长度与各段中长度最大的相同
AT 表达式 该段的起始地址定位在表达式所指定的节(16的整数倍)边界上
STACK 此参数在堆栈段中不可省略,用来指定该段为堆栈段,各个模块中的堆栈段采用顺序连接方式组合
MEMORY 本逻辑段定位在几个逻辑段中地址最高的存储区。当有多个MEMORY逻辑段连接时,除第一个带MEMORY参数的逻辑段外,其他带此参数的同名段按照COMMON方式处理
(5)‘类别名’,即分类名称,是用户字节定义的,长度不超过40个字符,用引号括起来的一个字符串。
3.段分配
指令格式:ASSUME CS:段名,DS:段名,ES:段名,SS:段名
功能:虽然SEGMENT/ENDS定义了一个完整的逻辑段,但并没有清楚的说明该逻辑段是代码段还是数据段,或者是其它类型的段,所以还必须配合使用ASSUME伪指令来明确逻辑段是数据段DS还是代码段CS还是附加段ES还是堆栈段SS。
注意:
(1)4个段不一定全部要定义,但是必须要有代码段。
(2)ASSUME不可省略一般放在代码段的开始
伪指令过程定义
也就是子程序
指令格式:
过程名 PROC [属性NEAR或FAR]
。。。
。。。
过程名 ENDP
举例:
Dchar proc ;过程名为Dchar
push ax ;保护寄存器
push bx
。。。。
。。。。
pop bx ;恢复寄存器
pop ax ;
ret ;子程序返回
Dchar endp ;过程结束