偽指令用來對匯編程序進行控制,對程序中的數(shù)據(jù)實現(xiàn)條件轉(zhuǎn)移、列表、存儲空間分配等處理,其格式和匯編指令一樣,但一般不產(chǎn)生目的代碼,即不直接命令cpu去執(zhí)行什么操作。
一、定義數(shù)據(jù)偽指令
該類偽指令用來定義存儲空間及其所存數(shù)據(jù)的長度。
· db:定義字節(jié),即每個數(shù)據(jù)是1個字節(jié)。
· dw:定義字,即每個數(shù)據(jù)占1個字(2個字節(jié))。
· dd:定義雙字,即每個數(shù)據(jù)占2個字。低字部分在低地址,高字部分在高地址。
· dq:定義4字長,即每個數(shù)據(jù)占4個字。
· dt:定義10個字節(jié)長,用于壓縮式十進制數(shù),
例如:data1db5,6,8,100
data2dw7,287
table db?;表示在table單元中存放的內(nèi)容是隨機的;
當(dāng)一個定義的存儲區(qū)內(nèi)的每個單元要放置同樣的數(shù)據(jù)時,可用dup操作符。
一般格式:countdup(?),count 為重復(fù)的次數(shù),“(?。敝袨橐貜?fù)的數(shù)據(jù)。
如:bufferdb100 dup(0);表示以buffer為首地址的100個字節(jié)中存放00h數(shù)據(jù)
buffer1 db100 dup(3,5,2dup(10),35),24,‘num’)
想一想存儲區(qū)的情況?
二、符號定義偽指令equ、=、及purge
· equ 偽指令給符號定義一個值。在程序中,凡是出現(xiàn)該符號的地方,匯編時均用其值代替,
如:timesequ50
data dbtimes dup(?)
上述兩個語句實際等效于如下一條語句:
datadb50 dup(?)
· “=”偽指令可給初始變量賦值。
如:count=100 ;count=100
time=50;time=50
· purge偽指令用于釋放由equ偽指令定義的變量,使這些變量可以被重新定義。
purgetimes ; 釋放times變量
timesequ2 ;重新定義
三、段定義偽指令segment和ends
一般來說,一個完整的匯編源程序由3個段組成,即堆棧段、數(shù)據(jù)段和代碼段。段定義偽指令可將源程序劃分成若干段,以便生成目的代碼和連接時將各同名段進行組合。
段定義偽指令一般格式為?。?
段名segment[定位類型] [組合類型] [類別]
段名 ends
segment和ends應(yīng)成對使用,缺—不可。其中段名是不可省略的。其它是可選項,是賦予段名的屬性,可以省略。
例如: datasegment
dw20dup(?)
dataends
四、設(shè)定段寄存器偽指令assume
一般格式: assume 段寄存器:段名[,段寄存器:段名,……]
功能:通知匯編程序,哪一個段寄存器是該段的段寄存器,以便對使用變量或標(biāo)號的指令匯編出正確的目的代碼。在段名中,code表示代碼段,data表示數(shù)據(jù)段,stack表示堆棧段。
由于assume偽指令只指明某一個段地址應(yīng)存于哪一個段寄存器中,并沒有包含將段地址送入該寄存器的操作。因此要將真實段地址裝入段寄存器還需用匯編指令來實現(xiàn)。這一步是不可缺少的。
例如,codesegment
assumecs:code,ds:data,ss:stack
movax,data;data段值送ax
movds,ax??;ax內(nèi)容送ds,ds才有實際段值
codeends
當(dāng)程序運行時,由于dos的裝入程序負(fù)責(zé)把cs初始化成正確的代碼段地址,ss初始化為正確的堆棧段地址,因此用戶在程序中就不必設(shè)置。但是,在裝入程序中ds寄存器由于被用作其它用途,因此,在用戶程序中必須用兩條指令對ds進行初始化,以裝入用戶的數(shù)據(jù)段地址。當(dāng)使用附加段時,也要用mov指令給es賦段地址。
五、定義過程的偽指令proc和endp
在程序設(shè)計中,可將具有一定功能的程序段看成為一個過程(相當(dāng)于一個子程序),它可以被別的程序調(diào)用。
一個過程由偽指令proc和endp來定義,其格式為:
過程名 proc[類型]
過程體
ret
過程名 endp
其中過程名是為過程所起的名稱,不能省略,過程的類型由far(遠過程,為段間調(diào)用)和near(近過程,在本段內(nèi)調(diào)用)來確定,如果缺省類型,則該過程就默認(rèn)為近過程。endp表示過程結(jié)束。過程體內(nèi)至少應(yīng)有一條ret指令,以便返回被調(diào)用處。過程可以嵌套,也可以遞歸使用。
例如一個延時100ms的子程序,其過程可定義如下,
delayproc
push bx
push cx
movbl,10
;延時10ms,改變bl和cx中的值,即可改變延時時間。
again: movcx,2801;
wait;loopwait
decbl
jnzagain
popcx
popbx
ret
delayendp
call delay??;調(diào)用該過程
遠過程調(diào)用時被調(diào)用過程必定不在本段內(nèi)。
例如,有兩個程序段,其結(jié)構(gòu)如下:
code1segment
assume cs:code1
farprocproc far
ret
farprocendp
code1 ends
code2segment
assume cs:code2
callfarproc
…..
code2 ends
code1 段中的farproc 過程被另一段code2調(diào)用,故為遠過程。
六、宏指令
在匯編語言書寫的源程序中,若有的程序段要多次使用,為了簡化程序書寫,該程序段可以用一條宏指令來代替,而匯編程序匯編到該宏指令時,仍會產(chǎn)生源程序所需的代碼。
宏指令的一般格式為:宏指令名macro[形式參量表]
宏體
endm
例如:shiftmacro
movcl,4
salal,cl
endm
這樣定義以后,凡是要使al中內(nèi)容左移4位的操作都可用一條宏指令shift來代替。
宏指令與子程序有許多類似之處。它們都是一段相對獨立的、完成某種功能的、可供調(diào)用的程序模塊,定義后可多次調(diào)用。但在形成目的代碼時,子程序只形成一段目的代碼,調(diào)用時轉(zhuǎn)來執(zhí)行。而宏指令是將形成的目的代碼插到主程序調(diào)用的地方。因此,前者占內(nèi)存少,但執(zhí)行速度稍慢;后者剛好相反。
七、org 偽指令
org偽指令規(guī)定了在某一段內(nèi),程序或數(shù)據(jù)代碼存放的起始偏移地址。
一般格式: org<表達式>
例如:datasegment
buff1 db 23,56h,‘eof’
org 2000h
buff2 db ‘string’
dataends
上述變量定義中,buff1從data段偏移地址為0的單元開始存放,而buff2則從data段偏移為2000h的單元開始存放,兩者不是連續(xù)存放。
八、匯編結(jié)束偽指令end
該偽指令表示源程序的結(jié)束.令匯編程序停止匯編。因此,任何一個完整的源程序均應(yīng)有end指令。
一般格式: end[表達式]
其中表達式表示該匯編程序的啟動地址。例如:
endstart??;表明該程序的啟動地址為start。