伪指令用来对汇编程序进行控制,对程序中的数据实现条件转移、列表、存储空间分配等处理,其格式和汇编指令一样,但一般不产生目的代码,即不直接命令cpu去执行什么操作。
一、定义数据伪指令
该类伪指令用来定义存储空间及其所存数据的长度。
· db:定义字节,即每个数据是1个字节。
· dw:定义字,即每个数据占1个字(2个字节)。
· dd:定义双字,即每个数据占2个字。低字部分在低地址,高字部分在高地址。
· dq:定义4字长,即每个数据占4个字。
· dt:定义10个字节长,用于压缩式十进制数,
例如:data1db5,6,8,100
data2dw7,287
table db?;表示在table单元中存放的内容是随机的;
当一个定义的存储区内的每个单元要放置同样的数据时,可用dup操作符。
一般格式:countdup(?),count 为重复的次数,“( )”中为要重复的数据。
如:bufferdb100 dup(0);表示以buffer为首地址的100个字节中存放00h数据
buffer1 db100 dup(3,5,2dup(10),35),24,‘num’)
想一想存储区的情况?
二、符号定义伪指令equ、=、及purge
· equ 伪指令给符号定义一个值。在程序中,凡是出现该符号的地方,汇编时均用其值代替,
如:timesequ50
data dbtimes dup(?)
上述两个语句实际等效于如下一条语句:
datadb50 dup(?)
· “=”伪指令可给初始变量赋值。
如:count=100 ;count=100
time=50;time=50
· purge伪指令用于释放由equ伪指令定义的变量,使这些变量可以被重新定义。
purgetimes ; 释放times变量
timesequ2 ;重新定义
三、段定义伪指令segment和ends
一般来说,一个完整的汇编源程序由3个段组成,即堆栈段、数据段和代码段。段定义伪指令可将源程序划分成若干段,以便生成目的代码和连接时将各同名段进行组合。
段定义伪指令一般格式为 :
段名segment[定位类型] [组合类型] [类别]
段名 ends
segment和ends应成对使用,缺—不可。其中段名是不可省略的。其它是可选项,是赋予段名的属性,可以省略。
例如: datasegment
dw20dup(?)
dataends
四、设定段寄存器伪指令assume
一般格式: assume 段寄存器:段名[,段寄存器:段名,……]
功能:通知汇编程序,哪一个段寄存器是该段的段寄存器,以便对使用变量或标号的指令汇编出正确的目的代码。在段名中,code表示代码段,data表示数据段,stack表示堆栈段。
由于assume伪指令只指明某一个段地址应存于哪一个段寄存器中,并没有包含将段地址送入该寄存器的操作。因此要将真实段地址装入段寄存器还需用汇编指令来实现。这一步是不可缺少的。
例如,codesegment
assumecs:code,ds:data,ss:stack
movax,data;data段值送ax
movds,ax ;ax内容送ds,ds才有实际段值
codeends
当程序运行时,由于dos的装入程序负责把cs初始化成正确的代码段地址,ss初始化为正确的堆栈段地址,因此用户在程序中就不必设置。但是,在装入程序中ds寄存器由于被用作其它用途,因此,在用户程序中必须用两条指令对ds进行初始化,以装入用户的数据段地址。当使用附加段时,也要用mov指令给es赋段地址。
五、定义过程的伪指令proc和endp
在程序设计中,可将具有一定功能的程序段看成为一个过程(相当于一个子程序),它可以被别的程序调用。
一个过程由伪指令proc和endp来定义,其格式为:
过程名 proc[类型]
过程体
ret
过程名 endp
其中过程名是为过程所起的名称,不能省略,过程的类型由far(远过程,为段间调用)和near(近过程,在本段内调用)来确定,如果缺省类型,则该过程就默认为近过程。endp表示过程结束。过程体内至少应有一条ret指令,以便返回被调用处。过程可以嵌套,也可以递归使用。
例如一个延时100ms的子程序,其过程可定义如下,
delayproc
push bx
push cx
movbl,10
;延时10ms,改变bl和cx中的值,即可改变延时时间。
again: movcx,2801;
wait;loopwait
decbl
jnzagain
popcx
popbx
ret
delayendp
call delay ;调用该过程
远过程调用时被调用过程必定不在本段内。
例如,有两个程序段,其结构如下:
code1segment
assume cs:code1
farprocproc far
ret
farprocendp
code1 ends
code2segment
assume cs:code2
callfarproc
…..
code2 ends
code1 段中的farproc 过程被另一段code2调用,故为远过程。
六、宏指令
在汇编语言书写的源程序中,若有的程序段要多次使用,为了简化程序书写,该程序段可以用一条宏指令来代替,而汇编程序汇编到该宏指令时,仍会产生源程序所需的代码。
宏指令的一般格式为:宏指令名macro[形式参量表]
宏体
endm
例如:shiftmacro
movcl,4
salal,cl
endm
这样定义以后,凡是要使al中内容左移4位的操作都可用一条宏指令shift来代替。
宏指令与子程序有许多类似之处。它们都是一段相对独立的、完成某种功能的、可供调用的程序模块,定义后可多次调用。但在形成目的代码时,子程序只形成一段目的代码,调用时转来执行。而宏指令是将形成的目的代码插到主程序调用的地方。因此,前者占内存少,但执行速度稍慢;后者刚好相反。
七、org 伪指令
org伪指令规定了在某一段内,程序或数据代码存放的起始偏移地址。
一般格式: org<表达式>
例如:datasegment
buff1 db 23,56h,‘eof’
org 2000h
buff2 db ‘string’
dataends
上述变量定义中,buff1从data段偏移地址为0的单元开始存放,而buff2则从data段偏移为2000h的单元开始存放,两者不是连续存放。
八、汇编结束伪指令end
该伪指令表示源程序的结束.令汇编程序停止汇编。因此,任何一个完整的源程序均应有end指令。
一般格式: end[表达式]
其中表达式表示该汇编程序的启动地址。例如:
endstart ;表明该程序的启动地址为start。