一、宏匯編
宏定義是用一組偽操作來實現的。其格式是:
macro_name MACRO [dumny_parameter_list]
... (宏定義體)
ENDM
其中MACRO和ENDM是一對偽操作.這對偽操作之間是宏定義體--是一組獨立功能的程序代碼.宏指令名(macro_name)給出該宏定義的名稱,調用時就使用宏指令名來調用該宏定義.其中啞元表(dumny_parameter_list)給出了該宏定義中所用到的形式參數(或稱虛參),每個啞元之間用逗號隔開.
經宏定義后的宏指令就可以在源程序中調用.這種對宏指令的調用稱為宏調用,宏調用的格式是:
macro_name [actual_parameter_list]
實元表(actual_parameter_list)中的每一項為實元,相互之間用逗號隔開.
1.宏定義可以無變元
宏定義:
SAVEREG MACRO
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
ENDM
宏調用:
SAVEREG
2.變元可以是操作碼
宏定義:
FOO MACRO P1,P2,P3
MOV AX,P1
P2 P3
ENDM
宏調用:
FOO WORD_VAR,INC,AX
宏展開:
+ MOV AX,WORD_VAR
+ INC AX
3.變元可以是操作碼的一部分,但在宏定義體中必須用&作為分隔符.
宏定義:
LEAP MACRO COND,LAB
J&COND LAB
ENDM
宏調用:
...
LEAP Z,THERE
...
LEAP NZ,HERE
...
宏展開:
...
+ JZ THERE
...
+ JNZ HERE
...
4.&是一個操作符,它在宏定義體中可以作為啞元的前綴,展開時可以把&前后個符號合并而形成一個符號,這個符號可以是操作碼,操作數或是一個字符串
宏定義:
PO MACRO P1
JMP TA&P1
ENDM
宏調用:
FO WORD_VAR
宏展開:
+ JMP TAWORD_VAR
5.實元是ASCII串的情況
宏定義:
MSGGEN MACRO LAB,NUM,XYZ
LAB&NUM DB 'HELLO MR.&XYZ'
ENDM
宏調用:
MSGGEN MSG,1,TAYLOR
宏展開:
+ MSG1 DB 'HELLO MR.TAYLOR'
6.宏指令名可以與指令助記符或偽操作名相同,在這種情況下,宏指令的優先級,而同名的指令或偽操作就失效了.偽操作PURGE可以用來在適當的時候取消宏定義,以便恢復指令的原始含義.
宏定義:
ADD MACRO OPR1,OPR2,RESULT
...
ENDM
宏調用:
...
ADD XX,YY,ZZ
PURGE ADD
...
在宏調用后,用PURGE偽操作取消定義,以便恢復ADD指令的原始含義,在PURGE ADD后面所用的ADD指令,則服從機器指令的定義.
PURGE偽操作可同時取消多個宏操作,此時各宏指令之間用逗號隔開.
7.LOCAL偽操作的使用.宏定義體內允許使用標號,如:
宏定義:
ABSOL MACRO OPER
CMP OPER,O
JGE NEXT
NEG OPER
NEXT:
ENDM
如果程序中多次調用該宏定義時,展開后會出現標號的多重定義.為此系統提供了LOCAL偽操作,其格式是
LOCAL list of local labels
其中局部標號表內的各標號之間用逗號隔開.匯編程序對LOCAL偽操作的局部標號表中的每一個局部標號建立的符號(用??0000~??FFFF)以代替在展開中存在的每個局部標號.必須注意,LOCAL偽操作只能用在宏定義體內,而且它必須是MACRO偽操作后的個語句,在MACRO和LOCAL偽操作之間還不允許有注釋和分號標志.
本例中的ABSOL宏定義在考慮有多次調用可能性的情況下,應定義為:
ABSOL MACRO OPER
LOCAL NEXT
CMP OPER,0
JGE NEXT
NEG OPER
NEXT:
ENDM
宏調用:
...
ABSOL VAR
...
ABSOL BX
...
宏展開:
...
+ CMP VAR,0
+ JGE ??0000
+ NEG VAR
+??0000:
...
+ CMP BX,0
+ JGE ??0001
+ NEG BX
+??0001:
...
8.宏定義中允許使用宏調用,其限制條件是:必須先定義后調用
宏定義:
DIF MACRO X,Y
MOV AX,X
SUB AX,Y
ENDM
DIFSQR MACRO OPR1,OPR2,RESULT
PUSH DX
PUSH AX
DIF OPR1,OPR2
IMUL AX
MOV RESULT,AX
POP AX
POP DX
ENDM
宏調用:
DIFSQR VAR1,VAR2,VAR3
9.宏定義體內不僅可以使用宏調用,也可以包含宏定義.
宏定義:
DEFMAC MACRO MACNAM,OPERATOR
MACNAM MACRO X,Y,Z
PUSH AX
MOV AX,X
OPERATOR AX,Y
MOV Z,AX
POP AX
ENDM
ENDM
其中MACNAM是內層的宏定義名,但又是外層宏定義的啞元,所以調用DEFMAC時,就形成一個宏定義.
宏調用:
DEFMAC ADDITION,ADD
宏展開:
+ ADDITION MACRO X,Y,Z
PUSH AX
MOV AX,X
ADD AX,Y
MOV Z,AX
POP AX
ENDM
形成加法宏定義ADDITION.同樣,宏調用
DEFMAC SUBTRACT,SUB
形成減法的宏定義.當然在形成這些宏定義后,就可以使用宏調用
ADDITION VAR1,VAR2,VAR3
而展開成:
+ PUSH AX
+ MOV AX,VAR1
+ ADD AX,VAR2
+ MOV VAR3,AX
+ POP AX
10.這里再介紹一個宏定義的變元中使用的偽操作%,它的格式是:
%expression
匯編程序把跟在%之后的表達式的值轉換成當前基數下的數,在展開期間,用這個數來取代啞元.
宏定義:
MSG MACRO COUNT,STRING
MSG&COUNT DB STRING
ENDM
ERRMSG MACRO TEXT
CNTR=CNTR+1
MSG % CNTR,TEXT
ENDM
宏調用:
...
CNTR=0
ERRMSG 'SYNTAX ERROR'
...
ERRMSG 'INVALID OPERAND'
...
宏展開:
...
+ MSG1 DB 'SYNTAX ERROR'
...
+ MSG2 DB 'INVALID OPERAND'
...
二、重復匯編
有時匯編語言程序需要連續地重復完全相同的或者幾乎完全相同的一組代碼,這時可使用重復匯編。
1.重復偽操作
其格式為:
REPT expression
... (重復塊)
ENDM
其中表達式的值用來確定重復塊的重復次數,表達式中如包含外部或未定義的項則匯編指示出錯.
重復偽操作并不一定要在宏定義體內,例如:
X=0
REPT 10
X=X+1
DB X
ENDM
則匯編后產生
+ DB 1
+ DB 2
+ DB 3
...
+ DB 10
把字符A到Z的ASCII碼填入數組TABLE
CHAR='A'
TABLE LABEL BYTE
REPT 26
DB CHAR
CHAR=CHAR+1
ENDM
用宏定義及重復偽操作把TAB,TAB+1,TAB+2,...,TAB+16的內容存入堆棧.
宏定義:
PUSH_TAB MACRO K
PUSH TAB+K
ENDM
宏調用:
I=0
REPT 17
PUSH_TAB % I
I=I+1
ENDM
要求建立一個100D字的數組,其中每個字的內容是下一個字的地址,而一個字的內容是個字的地址.
ARRAY LABEL WORD
REPT 99
DW $+2
ENDM
DW ARRAY
2.不定重復偽操作
(1)IRP偽操作
格式是:
IRP dummy,<argument list>
... (重復塊)
ENDM
匯編程序把重復塊的代碼重復幾次,每次重復把重復塊中的啞元用自變量表中的一項來取代,下一次取代下一項,重復次數由自變量表中的自變量個數來確定.自變量表必須用尖括號括起,它可以是常數,符號,字符串等.
例1:
IRP X,<1,2,3,4,5,6,7,8,9,10>
DB X
ENDM
匯編后得:
+ DB 1
+ DB 2
...
+ DB 10
例2:
IRP REG,<AX,BX,CX,DX>
PUSH REG
ENDM
匯編后得:
+ PUSH AX
+ PUSH BX
+ PUSH CX
+ PUSH DX
(2)IRPC偽操作
格式是:
IRPC dummy,string(或<string>)
... (重復塊)
ENDM
IRPC和IRP類似,但自變量表必須是字符串.重復次數由字符串中的字符個數確定,每次重復用字符串中的下一個字符取代重復塊中的啞元.例:
例1:
IRPC X,0 1 2 3 4 5 6 7
DB X+1
ENDM
匯編后得:
+ DB 1
+ DB 2
...
+ DB 8
例2:
IRPC K,A B C D
PUSH K&X
匯編后展開形成:
+ PUSH AX
+ PUSH BX
+ PUSH CX
+ PUSH DX
三、條件匯編
匯編程序能根據條件把一段源程序包括在匯編語言程序內或者把它排除在外,這里就用到條件偽操作.條件偽操作的一般格式是:
IFXX argument
... }自變量滿足給定條件匯編此塊
[ELSE]
... }自變量不滿足給定條件匯編此塊
ENDIF
自變量必須在匯編程序啟遍掃視后就成為確定的數值.條件偽操作中的XX表示條件如下:
IF expression 匯編程序求出表達式的值,如此值不為0則滿足條件.
IFE expression 如求出表達式的值為0則滿足條件.
IFDEF symbol 如符號已在程序中定義,或者已用EXTRN偽操作說明該符號是在外部定義的,則
滿足條件.
IFNDEF symbol 如符號未定義或未通過EXTRN說明為外部符號則滿足條件.
IFB <argument> 如自變量為空則滿足條件
IFNB<argument> 如自變量不為空則滿足條件
IFIDN <argu-1>,<argu-2> 如果字符串<arg-1>和字符串<arg-2>相同,則滿足條件.
IFDIF <argu-1>,<argu-2> 如果字符串<arg-1>和字符串<arg-2>不相同,則滿足條件.
條件偽操作可以用在宏定義體內,也可以用在宏定義體外,也允許嵌套任意次.
例1:宏指令MAX把三個變元中的值放在AX中,而且使變元數不同時產生不同的程序段.
宏定義:
MAX MACRO K,A,B,C
LOCAL NEXT,OUT
MOV AX,A
IF K-1
IF K-2
CMP C,AX
JLE NEXT
MOV AX,C
ENDIF
NEXT: CMP B,AX
JLE OUT
MOV AX,B
ENDIF
OUT:
ENDM
宏調用:
MAX 1,P
MAX 2,P,Q
MAX 3,P,Q,R
宏展開:
MAX 1,P
+ MOV AX,P
+??0001:
MAX 2,P,Q
+ MOV AX,P
+??0002:CMP Q,AX
+ JLE ??0003
+ MOV AX,Q
+??0003:
MAX 3,P,Q,R
+ MOV AX,P
+ CMP R,AX
+ JLE ??0004
+ MOV AX,R
+??0004:CMP Q,AX
+ JLE ??0005
+ MOV AX,Q
+??0005:
例2.宏指令GOTO L,X,REL,Y(其中REL可以是Z,NZ,L,NL等)可以根據不同情況產生無條件轉移指令或比較和條件轉移指令.
宏定義:
GOTO MACRO L,X,REL,Y
JFB <REL>
JMP L
ELSE
MOV AX,X
CMP AX,Y
J&REL L
ENDIF
ENDM
宏調用:
...
GOTO LOOP,SUM,NZ,15
...
GOTO EXIT
...
宏展開:
...
+ MOV AX,SUM
+ CMP AX,15
+ JNZ LOOP
...
+ JMP EXIT
例3.宏定義可允許遞歸調用,此時條件偽操作可用來結束宏遞歸
宏指令POWER可以用來實現X和2N相乘.這只需對X左移N次可實現,可以設COUNT為遞歸次數的計數值,當該數與N相等時即可結束遞歸調用.
宏定義:
POWER MACRO X,N
SAL X,1
COUTN=COUT+1
IF COUNT-N
POWER X,N
ENDIF
ENDM
宏調用:
COUTN=0
POWER AX,3
宏展開:
+ SAL AX,1
+ SAL AX,1
+ SAL AX,1
例4.宏指令BRANCH產生一條轉向X的轉移指令.當它相對于X的距離小于128字節時產生JMP SHORT X;否則產生JMP NEAR PTR X(X必須位于該轉移指令之后,即低地址區).
宏定義:
BRANCH MACRO X
IF ($-X) LT 128
JMP SHORT X
ELSE
JMP NEAR PTR X
ENDIF
ENDM
宏調用:
BRANCH X
宏展開:
如X與BRANCH指令間的距離小于128時產生
+ JMP SHORT X
否則產生:
+ JMP NEAR PTR X
匯編語言技術
更新時間: 2007-05-28 14:00:21來源: 粵嵌教育瀏覽量:1108