偽操作

偽操作是指令以外還可以由偽操作和 宏指令組成.是在 彙編程式對 源程式彙編期間由彙編程式處理的操作的電腦術語。

定義及特點

彙編語言程式語句除指令以外還可以由偽操作和宏指令組成.偽操作又稱偽指令,它不像機器指令那樣是在程式運行期間由計算機來執行的,它是在彙編程式源程式彙編期間由彙編程式處理的操作,它們可以完成如數據定義、分配存儲區、指示程式結束等功能。

一、數據定義及存儲器分配偽操作

這一類偽操作的格式是:
[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或T99vLE為模組取名字,NAME的格式是:
NAME module_name
彙編程式將以給出的module_name作為模組的名字.如果程式中沒有NAME偽操作,則也可使用T99vLE偽操作,其格式為:
T99vLE text
T99vLE偽操作可指定每一頁上列印的標題.同時,如果程式中沒有使用NAME偽操作,則彙編程式將用text中的前六個字元作為模組名.text最多可以60個字元.如果程式既無NAME又無T99vLE偽操作,則將用源程式檔案名稱作為模組名.
表示源程式結束的偽操作的格式為:
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,以免與十進制數發生混淆。
.字元串可以看成串常,可以用單引號或雙引號把字元串放在其中,得到的是字元串的ACSII值,例如:‘ABCD’。

七、過程定義偽操作

格式為:
procedure_name PROC Attribute
.
.
.
procedure_name ENDP
其中過程名為標識符,它又子程式入口的符號地址,它的寫法與標號的寫相同.屬性(Attribute)是指類型屬性,它可以是NEAR或FAR.段調用使用NEAR屬性,段間調用使用FAR屬性

相關詞條

相關搜尋

熱門詞條

聯絡我們