汇编编译器伪指令

来源:互联网 发布:it解决方案 编辑:程序博客网 时间:2024/05/17 04:59

汇编语言程序语句除指令以外还可以由伪操作和宏指令组成.伪操作又称伪指令,它不像机器指令那样是在程序运行期间由计算机来执行的,它是在汇编程序对源程序汇编期间由汇编程序处理的操作,这们可以完成如数据定义、分配存储区、指示程序结束等功能。

一、数据定义及存储器分配伪操作

这一类伪操作的格式是:

[Variable] Mnemonic Operand,...,Operand[;Comments]

其中变量(Variable)字段是可有可无的,它用符号地址表示,其作用与指令语句前的标号相同,但它的后面不跟冒号.如果语句中有变量则汇编程序使其记以第一个字节的偏移地址.

注释(Comments)字段用来说明该伪操作的功能,它也是可有可无的.

助记符(Mnemonic)字段说明所用伪操作的助记符,常用的有以下几种:

DB伪操作用来定义字节,其后的每个操作数都占有一个字节.

DW伪操作用来定义字,其后的每个操作数都占有一个字(低位字节在第一个字节地址中,高位字节在第二个字节地址中).

DD伪操作用来定义双字,其后的每个操作数占有二个字.

DQ伪操作用来定义四个字,其后的每个操作占有四个字.

DT伪操作用来定义十个字节(五个字),其后的每个操作数占有十个字节,形成压缩的BCD码.

操作数字段还可以使用复制操作符(duplication opreator)来复制某个操作数,例:

ARRAY1 DB 2 DUP(0,1,2,?)

注1:使用PTR属性操作符,可以指定操作数的类型属性.

例:

MOV AX,WORD PTR OPER1

注2:使用LABEL伪操作可以使同一变量具有不同的类型属性.

例:

BYTE_ARRAY LABEL BYTE

WORD_ARRAY DW 50 DUP(?)

二、表达式赋值伪操作EQU

格式:变量名 EQU 表达式

例:

CONST EQU 256 数赋以符号名

DATA EQU HEIGHT+12 地址表达式赋以符号名

ALPHA EQU 7

BETA EQU ALPHA-2

B EQU [BP+8] 变址引用赋以符号名B

P8 EQU DS:[BP+8]

另有一个与EQU类似的=伪操作也可以作为赋值操作使用.这们之间的区别是EQU伪操作中的表达式名是不允许重复定义的,而=伪操作则允许重复定义.

例:

EMP=7

EMP=EMP+1

三、段定义伪操作

存储器的物理地址是由段地址和偏移地址组合而成的,汇编程序在把源程序转换为目标程序时,必须确定标号和变量的偏移地址,并且需要把有关信息通过目标模块传送给连接程序,以便连接程序把不同的段和模块连接在一起形成一个可执行程序.为此,需要用到段定义伪操作,段定义伪操作的格式如下:

segment_name SEGMENT

...

segment_name ENDS

其中删节号部分,对于数据段、附加段和堆栈段来说,一般是存储单元的定义、分配等伪操作;对于代码段则是指令及伪操作。

此外,还必须明确段和段寄存储器的关系,这可用ASSUME伪操作来实现,其格式为:

ASSUME assignment,...,assignment

其中assignment说明分配情况,其格式为:

segment_register_name:segment_name

其中段寄存器名必须是CS、DS、ES和SS中的一个,而段名必须是由SEGMENT定义的段中的段名。而ASSUME NOTHING则可取消前面由ASSUME所指定的段寄存器。

由于ASSUME伪操作只是指定某个段分配给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中。但是,代码段不需要这样做,代码段的这一操作是在程序初始化时完成的。

SEGMENT伪操作还可以增加类型及属性的说明,格式如下:

segname SEGMENT [align_type]

[combine_type]

['class']

...

segname ENDS

一般情况下,这些说明可以不用.但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要使用这些说明.分别叙述如下:

.定位类型(align_type)可以是:

PARA 指定段的起始地址必须从小段边界开始,即段地址的最低的16进制数位必须为0.

BYTE 该段可以从任何地址开始

WORD 该段必须从字的边界开始,即段地址必须为偶数

PAGE 该段必须从页的边界开始,即段地址的最低两个16进制数位必须为0(该地址能被256整除)

.组合类型(combine_type)可以是:

PUBLIC 该段连接时将与有相同名字的其他分段连接在一起.其连接次序由连接命令指定.

COMMON 该段在连接时与其他同名分段有相同的起始地址,所以会产生覆盖.COMMON的连接长度是各分段中最大长度.

AT expression 使段的起始地址是表达式所计算出来的16位段地址.但它不能用来指定代码段.

STACK 指定该段在运行时为堆栈段的一部分.

MEMORY 指定该将分配在所有其他连接在一起的段的前面(在高地址上),如果连接时有几个指定MEMORY的段,则遇到的第一个段作为MEMORY段,其他段则作为COMMON段.

.类别('class') 连接时用于组成段组的名字.

四、程序开始和结束伪操作

在程序的开始可以用NAME或TITLE为模块取名字,NAME的格式是:

NAME module_name

汇编程序将以给出的module_name作为模块的名字.如果程序中没有NAME伪操作,则也可使用TITLE伪操作,其格式为:

TITLE text

TITLE伪操作可指定每一页上打印的标题.同时,如果程序中没有使用NAME伪操作,则汇编程序将用text中的前六个字符作为模块名.text最多可以60个字符.如果程序既无NAME又无TITLE伪操作,则将用源程序文件名作为模块名.

表示源程序结束的伪操作的格式为:

END [label]

其中标号指示程序开始执行的起始地址.如果多个程序模块相连接,则只有主程序要使用标号,其他子程序模块则只用END而不必指定标号.

五、对准伪操作

.EVEN伪操作使下一个字节地址成为偶数.一个字的地址最好从偶地址开始,所以对于字数组为保证其从偶地址开始,可以在它前面用EVEN伪操作来达到这一目的,例如:

DATA SEGMENT

...

EVEN

WORDAY DW 100 DUP(?)

...

DATA ENDS

.ORG Constant expression

如常数表达式的值为n,则ORG伪操作可以使下一个字节的地址为常数表达式的值n.

地址计数器的值可以用$来表示,汇编语言允许用户直接用$来引用地址计数器的值,因此:

ORG $+8

可以表示跳过8个字节的存储区.

JMP $+2

可以表示一条空指令,该指令只是延迟处理机的一些时间,而无其他功能.

六、基数控制伪操作

汇编程序默认的数为十进制数,因而除非专门指定,汇编程序把程序中出现的数均看作十进制数,为此,当使用其他基数表示的常数时,需要专门以标记如下:

.二进制数:由一串0、1组成其后跟以字母B,如00101100B

.十进制数:由0~9的数字组成。一般情况下后面不必加上标记,在指定其他基数的情况下,后面可跟字节字母D,如178D。

.十六进制数:由0~9及A~F组成的数,后面跟字母H。这个数的第一个字符必须是0~9,所以如果第一个字符是A~F时,应在其前加上数字0,如0FFFFH。

.八进制数:由数字0~7组成的数,后面可跟字母O或Q,如1777Q。

.RADIX伪操作,可以把默认的基数改变为2~16范围内的任何基数,其格式如下:

.RADIX expression

其中表达式用来表示基数值(用十进制表示)。

例如:

MOV BX,OFFH

MOV BX,178

.RADIX 16

MOV BX,0FF

MOV BX,178D

是等价的。应当注意,在用.RADIX 16把基数定为十六进制后,十进制数后都应跟字母D。在这种情况下,如果某个十六进制数的末字符为D,则应在其后跟字母H,以免与十进制数发生混淆。

操作数项伪操作

一、算术操作符

算术操作符有+-*/MOD

算术操作符可以用于数字表达式或地址表示式中。

二、逻辑操作符

它有ANDORXORNOT

逻辑操作符是按位操作的,它只能用于数字表达式中。

三、关系操作符

它有EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)六种。

关系操作符的两操作数必须都是数学或同一段内的两个存储器地址。计算的结果应为逻辑值:结果为真,表示0FFFFH;结果为假,则表示0。

例:

MOV BX,((PORT_VAL LT 5)AND 20)OR(PORT_VAL GE 5)AND 30)

则当PORT_VAL<5时,汇编结果是:

MOV BX,20

否则,汇编结果应该是:

MOV BX,30

四、数值回送(Value_returning)操作符

它有TYPE、LENGTH、SIZE、OFFSET、SEG 5种。这些操作符把一些特征或存储器地址的一部分作为数值回送。

.TYPE

格式为:TYPE Variable或label

如果是变量,则汇编程序将回送该变量的以字节数表示的类型:DB为1,DW为2,DD为4,DQ为8,DT为10.如果是标号,则汇编程序将回送代表该标号类型的数值:NEAR为-1,FAR为-2.

例:

ARRAY DW 1,2,3

则对于指令ADD SI,TYPE ARRAY

汇编程序将其形成为:

ADD SI,2

.LENGTH

格式为:LENGTH Variable

对于变量中使用DUP的情况,汇编程序将回送分配给该变量的单元数.而对于其他情况则回送1.

例:

FESS DW 100 DUP(0)

对于指令MOV CX,LENGTH FESS

汇编程序将其形成为:MOV CX,100

ARRAY DW 1,2,3

对于指令MOV CX,LENGTH ARRAY

汇编程序将其形成为:MOV CX,1

TABLE DB 'ABCD'

对于指令MOV CX,LENGTH TABLE

汇编程序将其形成为:MOV CX,1

.SIZE

格式为:SIZE Variable

汇编程应回送分配给该变量的字节数.但是,此值是LENGTH值和TYPE值的乘积,例:

FEES DW 100 DUP(0)

MOV CX,SIZE FEES

将形成为:MOV CX,200

.OFFSET

格式为:OFFSET Variable或label

汇编程序将回送变量或标号的偏移地值

.SEG

格式为:SEG Variable或label

汇编程序将回送变量或标号的段地址值.

五、属性操作符

它有PTR、段操作符、SHORT、THIS、HIGH和LOW 6种

.PTR

格式为:type PTR expression

PTR用来建立一个符号地,但它本身并不分配存储器,只是用来给已分配的存储地址赋予另一种属性,使该地址具有另一种类型.格式中的类型字段表示所赋予的新类型属性,而表达式字段则是被取代类型的符号地址

例:MOV BYTE PTR[BX],5

或:MOV WORD PTR[BX],5

.段操作符:用来表示一个变量、变量地址表达式的段属性。例如,用段前缀指定某段的地址操作数

MOV AX,ES:[BX+SI]

可见它是用段寄存器:地址表达式来表达的。此外,也可以用段名:地址表达式或组名:地址表达式来表示其段属性。

.SHORT

用来修饰JMP指令中转向地址的属性,指出转向地址是在下一条指令地址的+(-)127个字节范围之内.

例:JMP SHORT TAG

.THIS

格式为: THIS attribute或type

它可以象PTR一样建立一个指定类型(BYTE、WORD或DWORD)的或指定距离(NEAR或FAR)的地址操作数.该操作数的段地址和偏移地址与下一个存储单元地址单元相同.

例如: FIRST_TYPE EQU THIS BYTE

WORD_TABLE DW 100 DUP(?)

此时FIRST_TYPE的偏移地址值和WORD_TABLE完全相同,但它是字节类型的,而WORD_TABLE则是字类型的.

又如:START EQU THIS FAR

MOV CX,100

这样,MOV指令有一个FAR属性的地址START,这样允许其他段的JMP指令直接跳到START来.

.HIGH和LOW

称为字节分离操作符,它接收一个数或地址表达式,HIGH取其高位字节,LOW取其低位字节.例如:

CONST EQU 0ABCDH

则 MOV AH,HIGH CONST

将汇编成MOV AH,0ABH

0 0
原创粉丝点击