![子程序與宏指令設計_第1頁](http://file4.renrendoc.com/view14/M05/3B/1F/wKhkGWcWd6uAAzu5AAEmaEzU4Sk712.jpg)
![子程序與宏指令設計_第2頁](http://file4.renrendoc.com/view14/M05/3B/1F/wKhkGWcWd6uAAzu5AAEmaEzU4Sk7122.jpg)
![子程序與宏指令設計_第3頁](http://file4.renrendoc.com/view14/M05/3B/1F/wKhkGWcWd6uAAzu5AAEmaEzU4Sk7123.jpg)
![子程序與宏指令設計_第4頁](http://file4.renrendoc.com/view14/M05/3B/1F/wKhkGWcWd6uAAzu5AAEmaEzU4Sk7124.jpg)
![子程序與宏指令設計_第5頁](http://file4.renrendoc.com/view14/M05/3B/1F/wKhkGWcWd6uAAzu5AAEmaEzU4Sk7125.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
為了程序共享或模塊化設計的需要,
可以把一段公共語句序列設計成子程序或
宏指令的形式。
6.1子程序結(jié)構(gòu)及設計方法
6.2子程序參數(shù)傳遞
6.3嵌套與遞歸子程序
6.4宏指令
6.5宏指令庫
6.6重復偽指令
6.7條件偽指令
工6.1子程序結(jié)構(gòu)及設計方法
6.1.1含有子程序的程序結(jié)構(gòu)
在匯編語言中用過程定義偽指令定
義子程序。過程定義偽指令格式:
過程名PROC屬型
過程名ENDP
調(diào)用程序和子程序在同一個代碼段的程
序結(jié)構(gòu)(子程序類型可缺省,注意END后必須
跟空程序名)
CODESEGMENT
MAINPROCFAR
???
CALLSUB1
RET
MAINENDP
SUB1PROC
RET
SUB1ENDP
CODEENDS
ENDMAIN
-馬調(diào)用程序和子程序在不同段的程序結(jié)構(gòu)
森0B繆被段間調(diào)用又被段內(nèi)調(diào)用,必須是FAR屬性
C知季顯式說明是FAR屬性)
■-W/
CODE1SEGMENT
MAINPROCFAR
CALLFARPTRSUB2
RET
MAINENDP
CODE1ENDS
C0DE2SEGMENT
SUB1PROCFAR
CALLFARPTRSUB2
RET
SUB1ENDP
SUB2PROCFAR
RET
SUB2ENDP
C0DE2ENDS
ENDMAIN
Qr.2設計子程序時應注意的問題
1.子程序說明
2.寄存器的保存與恢復
3.密切注意堆棧狀態(tài)
-
6.2子程序參數(shù)傳遞
可以通過給子程序傳遞參數(shù)使其更
通用。常用的參數(shù)傳遞方法如下:通過
寄存器傳遞;若調(diào)用程序和子程序在同
模塊(源程序)中,子程序可以直接訪
問模塊中的變量;通過地址表傳遞參數(shù)
地址;通過堆棧傳遞參數(shù)或參數(shù)地址。
6.2.1通過寄存器傳遞
這種傳遞方式使用方便,適用于參數(shù)較少的
情況。
例1.把BX中的16位二進制數(shù)轉(zhuǎn)換成
十進制并顯示在屏幕上。
程序6.3
STASGSEGMENT
DW32DUP(?)
STASGENDS
CODESEGMENT
ASSUMECS:CODE
MAINPROCFAR
MOVBX,162EH
CALLTERN
MOVAX,4C00H
INT21H
MAINENDP
PROC;二一十并顯示。
MOVCX,10000
CALLDEC_DIV;轉(zhuǎn)換萬位數(shù)
MOVCX,1000
CALLDEC_DIV;轉(zhuǎn)換千位數(shù)
MOVCX,100
CALLDEC_DIV;轉(zhuǎn)換百位數(shù)
MOVCX,10
CALLDEC_DIV;轉(zhuǎn)換十位數(shù)
MOVCX,1
CALLDEC_DIV;轉(zhuǎn)換個位數(shù)
RET
TERNENDP
PROC;ex中為十進制的位權(quán)
MOVAX,BX
MOVDX,0
DIVCX;商為轉(zhuǎn)換后的一位十進制數(shù)
MOVBX,DX
MOVDL,AL
ADDDL,30H;轉(zhuǎn)換成ASCII碼
MOVAH,2;顯示
INT21H
RET
DEC.DIVENDP
CODEENDS
ENDMAIN」
6^2同模塊中的子程序可直接訪問模塊中的變量
若調(diào)用程序和子程序在同模塊中,子程序
可以直接訪問模塊中的變量。
例2.實現(xiàn)數(shù)組求和功能。要求數(shù)組求
和(不考慮溢出情況)由子程序?qū)崿F(xiàn),其數(shù)
組元素及結(jié)果均為字型數(shù)據(jù)。見程序6.4。
STACKSGSEGMENTSTACK'STK,
DW32DUP('S')
STACKSGENDS
DATASEGMENT
ARYDW1,2,3,4,5,6,7,8,9,10
COUNTDW($-ARY)/2;數(shù)組元素個數(shù)
SUMDW?;數(shù)組和的地址
DATAENDS
C0DE1SEGMENT
學TIAINPROCFAR
ASSUMECS:CODE1,DS:DATA
PUSHDS
XORAX,AX
PUSHAX
MOVAX,DATA
MOVDS,AX
CALLFARPTRARY_SUM
RET
MAINENDP
C0DE1ENDS
C0DE2SEGMENT
ASSUMECS:C0DE2
ARY_SUMPROCFAR;數(shù)組求和子程序
PUSHAX;保存寄存器
PUSHCX
PUSHSI
LEASI,ARY;取數(shù)組起始地址
MOVCX,COUNT;取元素個數(shù)
XORAX,AX;清0累加器
ADDAX,[SI];累加和
ADDSI,TYPEARY;修改地址指針
LOOPNEXT
MOVSUM,AX;存和
POPSI;恢復寄存器
POPCX
POPAX
RET
ARY_SUMENDP
C0DE2ENDS
ENDMAIN
*
6.堂通過地址表傳遞參數(shù)地址
?適用于參數(shù)較多的情況。具體方法是先建立一個
地址表,該表由參數(shù)地址構(gòu)成。然后把表的首地址通過
寄存器或堆棧傳遞給子程序。
例3.編寫一個數(shù)組求和子程序,
其數(shù)組元素及結(jié)果均為字型數(shù)據(jù)。另
定義兩個數(shù)組,并編寫一個主程序,
通過調(diào)用數(shù)組求和子程序分別求出兩
個數(shù)組的和。見程序6.5。
程序6.5
KSGSEGMENTSTACK'STK,
STACKSGENDS
DATASEGMENT
;數(shù)組1
COUNTDW($-ARY)/2;數(shù)組1的元素個數(shù)
SUM;數(shù)組1的和地址
NUM10,20,30,40,50;數(shù)組2
($-NUM)/2;數(shù)組2的元素個數(shù)
TOTAL;數(shù)組2的和地址
TABLEDW3DUP(?);地址表
DATAENDS
,0DE1SEGMENT
#+KPROCFAR
J---
ASSUMECS:CODE1,DS:DATA
PUSHDS
XORAX,AX
PUSHAX
MOVAX,DATA
MOVDS,AX;構(gòu)造數(shù)組1的地址表
MOVTABLE,OFFSETARY
MOVTABLE+2,OFFSETCOUNT
MOVTABLE+4,OFFSETSUM
LEABX,TABLE;傳遞地址表首地址
CALLFARPTRARY_SUM,
二;構(gòu)造數(shù)組2的地址表
MOVTABLE,OFFSETNUM
MOVTABLE+2,OFFSETCT
MOVTABLE+4,OFFSETTOTAL
LEABX,TABLE
;傳遞地址表的首地址
CALLFARPTRARY_SUM
;段間調(diào)用調(diào)用數(shù)組求和子程序
RET
MAINENDP
CODE1ENDS
SEGMENT
ASSUMECS:C0DE2
ARY_SUMPROCFAR;數(shù)組求和子程序
PUSHAX;保存寄存器
PUSHCX
PUSHSI
PUSHDI
MOVSI,[BX]取數(shù)組起始地址
MOVDI,[BX+2]取元素個數(shù)地址
MOVCX,[DI]取元素個數(shù)
MOVDI,[BX+4]取結(jié)果地址
XORAX,AX清0累加器,
ADDAX,[SI];累加和
ADDSI,TYPEARY;修改地址指針
LOOPNEXT
MOV[DI],AX;存和
POPDI;恢復寄存器
POPSI
POPCX
POPAX
RET
ARY_SUMENDP
C0DE2ENDS
ENDMAIN
6,他通過堆棧傳遞參數(shù)或參數(shù)地址
這種方式適用于參數(shù)較多,或子程序有多層
嵌套、遞歸調(diào)用的情況。
步驟:
?主程序把參數(shù)或參數(shù)地址壓入堆棧;
?子程序使用堆棧中的參數(shù)或通過棧中參數(shù)地址取到參數(shù);
?子程序返回時使用RETn指令調(diào)整SP指針,以便刪除堆棧中已用過
的參數(shù),保持堆棧平衡,保證程序的正確返回。
麻完成數(shù)組求和功能,求和由子程序?qū)?/p>
現(xiàn),:要求通過堆棧傳遞參數(shù)地址。
程序6.6
STACKSGSEGMENTSTACK'STK,
DW16DUP(?)
STACKSGENDS
DATASEGMENT
ARYDW1,2,3,4,5,6,7,8,9,10
COUNTDW($-ARY)/2
SUMDW?
DATAENDS
C0DE1SEGMENT
MAINPROCFAR
ASSUMECS:CODE1,DS:DATA
PUSHDS{)
XORAX,AX
PUSHAX;⑵
MOVAX,DATA
MOVDS,AX
LEABX,ARY
PUSHBX;⑶壓入數(shù)組起始地址
LEABX,COUNT
PUSHBX;⑷壓入元素個數(shù)地址
LEABX,SUM
PUSHBX;(5)壓入和地址
CALLFARPTRARYSUM
"6)調(diào)用求和子程序
MAINENDP
CODE1ENDS
SEGMENT
ASSUMECS:C0DE2
ARYSUMPROCFAR數(shù)組求和子程序
PUSHBP⑺保存BP值
MOVBP,SPBP是堆棧數(shù)據(jù)的地址指針
PUSHAX⑻保存寄存器內(nèi)容
PUSHCX(9)
PUSHSI10
PUSHDI(11)
MOVSI,[BP+1O1得到數(shù)組起始地址
MOVDI,[BP+8]得到元素個數(shù)地址
MOVCX,DI得到元素個數(shù)
MOVDI,LBP+6J得到和地址
XORAX,AX
ADDAX,[SI];累加
ADDSI,TYPEARY;修改地址指針
LOOPNEXT
MOV[DI],AX存和
POPDI?恢復寄存器內(nèi)容
POPSI(13)
POPCX(14)
POPAX(15)
POPBP(16)
RET6?返回并調(diào)整SP指針
ARY_SUMENDP
C0DE2ENDS
ENDMAIN
DI值語句(11)執(zhí)行后堆棧狀態(tài)
SI值語句⑩執(zhí)行后堆棧狀態(tài)
CX值語句⑼執(zhí)行后堆棧狀態(tài)
AX值語句⑻執(zhí)行后堆棧狀態(tài)
BPABP值語句⑺執(zhí)行后堆棧狀態(tài)
IP值語句⑹執(zhí)行后堆棧狀態(tài)
CS值
SUM的地址語句⑸執(zhí)行后堆棧狀態(tài)
COUNT地址語句⑷執(zhí)行后堆棧狀態(tài)
ARY首地址語句⑶執(zhí)行后堆棧狀態(tài)
0語句⑵執(zhí)行后堆棧狀態(tài)
PSP段基址語句⑴執(zhí)行后堆棧狀態(tài)
程序6.6中所有入棧操作對堆棧的影響
DI值
SI值
CX值
AX值
BP值
IP值
CS值
SUM的地址
COUNT地址
ARY首地址
0語句(17)執(zhí)行后堆棧狀態(tài)
PSP段基址
程序6.6中主程序的RET執(zhí)行前堆棧狀態(tài)
例5.完成數(shù)組求和功能,其中
由子程序?qū)崿F(xiàn),要求使用結(jié)構(gòu)
編碼見程序6.7。
堆棧數(shù)據(jù)結(jié)構(gòu)字段名
DI值
SI值
CX值
AX值
BP值SAVE_BP'
IP值SAVE_CS_IP
CS值
SUM的地址SUM_ADDR吆吉構(gòu)
COUNT地址COUNT_ADDR
ARY首地址ARYADDR,
0
PSP段基址
程序6.7的堆棧及結(jié)構(gòu)數(shù)據(jù)示意圖i反
程序6.7
STACKSGSEGMENTSTACK'STK'
DW16DUP('S')
STACKSGENDS
DATASEGMENT
ARYDW1,2,3,4,5,6,7,8,9,10
COUNTDW($-ARY)/2
SUMDW?
DATAENDS
CODE1SEGMENT
MAINPROCFAR
ASSUMECS:CODE1,DS:DATA
PUSHDS
XORAX,AX
PUSHAX
MOVAX,DATA
MOVDS,AX
LEABX,ARY
PUSHBX;壓入數(shù)組起始地址
LEABX,COUNT
PUSHBX;壓入元素個數(shù)地址
LEABX,SUM
PUSHBX;壓入和地址
CALLFARPTRARYSUM
MAINENDP
CODE1ENDS
C0DE2SEGMENT
ASSUMECS:C0DE2
STACK_STRCSTRUG;定義結(jié)構(gòu)
SAVE_BPDW
SAVE_CS_IPDW2DUP(?)
SUM_ADDRDW?
COUNT_ADDRDW?
ARY_ADDRDW?
STACK_STRCENDS、
HSRY_SUMPROCFAR;數(shù)組求和子程序
PUSHBP;保存BP值
MOVBP,SP
PUSHAX
PUSHCX
PUSHSI
PUSHDI
MOVSI,[BP].ARY_ADDR;數(shù)組文臺地址
MOVDI,[BP].COUNT_ADDR
MOVCX,[DI]
MOVDI,[BP],SUM_ADDR;得至ij和地址
XORAX,AX
L^IEXT:ADDAX,[SI];累加
冬>ADDSI,TYPEARY;修改地址指針
?LOOPNEXT
MOV[DI],AX;存和
POPDI
POPSI
POPCX
POPAX
POPBP
RET6;返回并調(diào)整SP指針
ARY_SUMENDP
C0DE2ENDS
ENDMAIN上
r*.6.3嵌套與遞歸子程序
*1.子程序嵌套
主程序SUB1SUB2
子程序嵌套示意圖返回
2.遞歸子程序
以下是求N!遞歸過程的描述。編碼見程
序6.8。
BE&iN,FACT(N,RESULT)
SAVEREGISTERONSTACK
IFN=O
RESULT-1
ELSE
PUSHADDRESSOFRESULTONTOSTACK
PUSHN-1ONTOSTACK
CALLFACT(N-1,RESULT)
RESULT-N*RESULT
ENDIF
RESTOREREGISTERSFROMSTACK
DELETEPARAMETERSFROMSTACK
莓>程序6.8
STACKSGSEGMENTSTACK'S';定義堆棧
DW128DUP('ST')
STACKSGENDS
DATASEGMENT
N_VALDW3;定義N值
RESULTDW?;結(jié)果
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA,SS:STACKSG
FRAMESTRUG;定義幀結(jié)構(gòu)
SAV_BPDW?:保存BP值
SAV_CS_IPDW2DUP(?);保存返回地址
NDW?;當前N值
RESULT_ADDRDW?;結(jié)果地址
FRAMEENDS
PROCFAR
MOVAX,DATA
MOVDS,AX
LEABX,RESULT
PUSHBX;結(jié)果地址入棧
PUSHN_VAL;N值入棧
CALLFARPTRFACT
;調(diào)用遞歸子程序
R1:MOVAX,4C00H
INT21H
MAINENDP
PROCFAR;N!遞歸子程序
PUSHBP;保存BP值
MOVBP,SP;BP指向幀基地址
PUSHBX
PUSHAX
MOVBX,[BP].RESULTADDR
MOVAX,[BP].N;取幀中N值
CMPAX,0
JEDONE;N=O時退出子程序嵌套
PUSHBX;為下一次調(diào)用壓入結(jié)果地址
DECAX
PUSHAX;為下一次調(diào)用壓入(N—1)值
CALLFARPTRFACT
MOVBX,[BP].RESULT_ADDR
MOVAX,[BX];取中間結(jié)果(N—1)!
MUL[BP].N;N*(N-1)!
JMPSHORTRETURN
DONE:MOVAX,1;O!=1
RETURN:MOV[BX],AX;存中間結(jié)果
POPAX
POPBX
POPBP
RET4
FACTENDP
CODEENDS
ENDMAIN/
程序6.8的運行情況:
①主程序把結(jié)果地址和N的初始值壓
入堆棧,然后調(diào)用FACT子程序。
②在FACT中,它不斷調(diào)用自身,每調(diào)
用一次都要在堆棧中形成一幀,該幀由以
下信息組成:子程序中要用到的寄存器內(nèi)
容、中間結(jié)果地址、(N-1)的值、子程
序返回地址,自身調(diào)用直到N=0為止。
③當N=0時開始返回。
④通過[BP].RESULT_ADDR和[BP].N取
出堆棧中本次使用的參數(shù),計算N*(N-
1)!的值,保存中間結(jié)果,恢復寄存器的
爭,用RET4返回并廢除已用過的N和中
間結(jié)果地址。
⑤重復第④步,逐層返回直到N等
于初始值為止。
嗨-6.4.1宏定義、宏調(diào)用、宏擴展
宏指令是源程序中一段有獨立功
能的程序代碼。宏指令由宏定義偽指
令定義,它只需在源程序中定義一次
,便可以多次被調(diào)用。
★宏定義偽指令格式:
宏指令名MACRO[形式參數(shù)表]
...;宏指令體
ENDM
例1.輸入一個字符的宏定義、宏調(diào)用、宏擴展
INCHARMACRO
MOVAH,1
INT21H;輸入的字符在AL
ENDM
;宏調(diào)用
INCHAR
當匯編程序匯編到宏指令INCHAR時,則對其擴
展如下:
1MOVAH,1
1INT21H
指令前的“1”表示該語句是擴展時替換
得到的。
f1一
,嗎J設計宏指令時應注意的問題
由于宏指令也像子程序那樣可以被多次
調(diào)用或被多個程序共享,所以在設計時需要
注意以下問題:
1.宏指令說明
2.寄存器的保存與恢復
3.宏指令中的符號說明
整」6.4.2LOCAL偽指令
格式:LOCAL局部符號表
功能:對局部符號表中的每個符號,在匯編時每
擴展一次便建立一個惟一的符號,形如??XXXX(
xxxx的值在0000孑FFF之間)。以保證匯編時生成名字的
惟一性。
尸繁例2.以下是定義一個延時程序的宏指令delay,并且在同
值—一個程序中兩次被調(diào)用的擴展情況。
;宏定義
DELAYMACRO
LOCALLOP
MOVCX,2801
LOP:LOOPLOP
ENDM
宏調(diào)用:
^^WJELAY
DELAY
匯編時宏擴展如下:
DELAY
0009B90AF1■IMOVCX,2801
ooocE2FE1??0000:LOOP??0000
DELAY
OOOEB90AF11MOVCX,2801
0011E2FE1??0001:LOOP??000
瑞?宏指令中參數(shù)的使用
在宏定義時可以帶有形式參數(shù),而在宏
調(diào)用時給出實參數(shù)即可。
宏指令的參數(shù)可以是常數(shù)、寄存器、變
量、表達式、操作碼或操作碼的一部分、指
令或偽指令助記符等。
例3.定義在兩個字型內(nèi)存變量之間傳送數(shù)據(jù)的宏
指令,并調(diào)用它,然后觀察其擴展情況。
MOVEMOCROX,Y
PUSHAX
MOVAX,X
MOVY,AX
POPAX
ENDM
SEGMENT
VAR1DW6543H
VAR2
DATAENDS
;右調(diào)用;右擴展
MOVEVAR1,VAR2iPUSHAX
1MOVAX,VAR1
1MOVVAR2,AX
1POPAX
飛j643宏指令嵌套
宏指令嵌套有兩種情況:
.宏定義體中含有宏調(diào)用
?宏定義體中含有宏定義
例14.宏定義體中嵌套宏定義的宏指令、宏調(diào)用及宏擴展示例。
DMACMACROMNAME,OPER;外層宏定義
MNAMEMACROX,Y,Z;內(nèi)層宏定義
PUSHAX
MOVAX,X
OPERAX,Y
MOVZ,AX
POPAX
ENDM
ENDM
DW25
逐jDW12
YDW9
■
??
DMACADDITION,ADD;外層宏調(diào)用
1ADDITIONMACROX,Y,Z
1PUSHAX
1MOVAX,X
ADDAX,Y
MOVZ,AX
POPAX
ENDM
ADDITIONA,B,C;內(nèi)層右調(diào)用
1PUSHAX
1MOVAX,A
1ADDAX,B
1MOVC,AX
1POPAX
DMACLOGIC_AND,AND;外層宏調(diào)用
1LOGIC_ANDMACROX,Y,Z
1PUSHAX
1MOVAX,X
1ANDAX,Y
1MOVZ,AX
1POPAX
1ENDM
FLDGICANDA,B,C;內(nèi)層右調(diào)用
IPUSHAX
1MOVAX,A
1ANDAX,B
1MOVC,AX
1POPAX
使用適當?shù)膶崊?shù),通過調(diào)用DMAC宏指令可
以生成另一條新的宏指令,再調(diào)用新宏指令可
以實現(xiàn)任何雙操作數(shù)指令的操作,而且兩個操
作數(shù)可以同時為存儲器操作數(shù)。這種方法使
宏的功能更強大。
■/URGE偽指令
格式:PURGE宏指令名....
功能:從內(nèi)存中刪除指定的宏指令
例:
PURGEINCHAR
6.4.4宏操作符
這些操作符不僅適用于宏指令,也適用于
重復匯編偽指令。
宏操作符格式名稱
&參數(shù)文本替換操作符
<字符串〉文本原樣傳遞操作符
!字符字符原意操作符
%表達式表達式操作符
"注釋宏注釋
1.操作符&
在宏定義體中&可以作為形式參數(shù)的前綴,而當宏擴展
時則把&前后兩個符號合并形成一個符號,這個符號可以是操
作碼、操作數(shù)或是一個字符串。
例5.下面定義的PutData宏指令中,參數(shù)TheName作為
變量名的一部分,通過&把前后兩個符號合并成一個變量名。
在Ju叩宏指令中,參數(shù)Cond作為操作碼的一部分,通過&把前
后兩個符號合并成一個指令助記符。
⑴PUTDATA宏指令
PUTDATAMACROTHENAME,THEDATA
PD&THENAMEDBTHEDATA
ENDM
;宏調(diào)用
PUTDATAMYDATA,5
;宏擴展
1PDMYDATADB5
⑵JUMP宏指令
JUMPMACROCOND,L
J&CONDL
ENDM
;宏調(diào)用
JUMPNE,LAB1
;宏擴展
1JNELAB1
二在宏指令中,當使用&操作符生成的是
一個變量名或標號時,同樣要注意在一個程
序中多次調(diào)用同一個宏指令時出現(xiàn)的符號重
定義錯誤。若有這種可能性,應把名字用
LOCAL偽指令說明成局部的。如下所示:
;宏定義
PUTDATAOMACROTHENAME,THEDATA
LOCALPD_&THENAME
PD_&THENAMEDBTHEDATA
ENDM
;宏調(diào)用
PUTDATAOMYDATA,5
;宏擴展
1??OOOOMYDATADB5
;宏調(diào)用
PUTDATAOMYDATA,8
;宏擴展
1??OOO1MYDATADB8
返叵
2.文本原樣傳遞操作符<>
嗎血9>操作符括起的內(nèi)容作為一個整體原樣傳遞。
力U如,可以使用<>符號包圍目標,從而使該目標作為單
一的參數(shù)而不是多個參數(shù)的列表。
例6.用不同的實參數(shù)調(diào)用PUTDATA宏指令,觀察它們的變化。
PUTDATAMACROTHENAME,THEDATA
PD_&THENAMEDBTHEDATA
ENDM
;宏調(diào)用1
PUTDATAMYDATA,5,4,3
;宏擴展
1PD_MYDATADB5
;宏調(diào)用2
PUTDATAMYDATA,<5,4,3>
;宏擴展
1PD_MYDATADB5,4,3
Numeric=10+2
TextuaIequ<10+2>
其匯編結(jié)果是:
NUMERIC.................NUMBER000C
TEXTUAL................TEXT10+2
可以看到,對Numeric已經(jīng)求值,而
TextuaI只是一串字符而已。一
y■■..
駕字符原意操作符!
!操作符指示MASM把后跟的一個字符原樣傳送
,即把它只作為普通字符對待。
例如,若你需要把“!&>%”符號中的一個作為
宏指令中的字符,可以使用!操作符。
例7.以下宏調(diào)用的第二個實參數(shù)是一串警告信息,其中最
符希望是感嘆號“!”。但“!”是宏操作符,要想把
當做其原意感嘆號對待,就需在它前邊加上宏操作符!。
;宏定義
DEBUGMSGMACROPOINT,STRING
MSG&POINTDB,ATPOINT&POINT:&STRING,
;宏調(diào)用,其中第一個!為宏操作符,第二個??;是感嘆號
DEBUGMSG6,<INSERTIONFAILS!!>
;宏擴展
1MSG6DB'ATPOINT6:INSERTIONFAILS!'
4.表達式操作符%
j在宏調(diào)用時,%操作符強迫后跟的表達式立即求值,并
把表達式的結(jié)果作為實參數(shù)替換,而不是表達式本身。
例8.定義Probleml宏指令,并比較兩次調(diào)用Problend
宏指令的區(qū)別,其中一次調(diào)用中使用了%操作符。
Probleml宏指令功能:把由宏指令參數(shù)所指定的字型數(shù)
組(array)的一個元素裝入AX寄存器,該參數(shù)經(jīng)匯編后必須
是一個常數(shù)表達式。
MACROPARAMETER
MOVAX,ARRAY[PARAMETER*2]
ENDM
;宏調(diào)用L希望取出ARRAY】2,其中的參數(shù)〃10+2〃是表達式本身
PR0BLEM110+2
宏擴展L1MOVAX,ARRAY[10+2*2]
實際取出的是ARRAY,,正確的表達是:
宏調(diào)用2:PR0BLEM1%10+2
宏擴展2:1MOVAX,ARRAY[12*2]
注意:由于MASM在調(diào)用宏指令時對
其中的參數(shù)經(jīng)常是原文替換,所以有時
產(chǎn)生的可能不是預期的結(jié)果。
考慮以下對PR0BLEM1的宏調(diào)用及宏擴展:
;宏調(diào)用,要求裝入ARRAY的元素2
PR0BLEM12
;宏擴展
1MOVAX,ARRAY[2*2]
可以看到,宏擴展后結(jié)果正確。
廣宏調(diào)用:裝入ARRAY的元素10:
INDEX=8
PR0BLEM1INDEX+2
;宏擴展
1MOVAX,ARRAY[INDEX+2*2]
因為MASM的地址表達式遵守操作符優(yōu)先
級的優(yōu)先規(guī)則,則該語句宏擴展后不是預想
的結(jié)果,它訪問的是元素6(索引12),而
不是元素10(索引20)。
貨為了能夠得到正確的結(jié)果,可以在宏指
令的參數(shù)表達式中用()把參數(shù)括起來:
;曉義
PR0BLEM2MACROPARAMETER
MOVAX,ARRAY[(PARAMETER)*2]
ENDM
;宏調(diào)用
INDEX=8
PR0BLEM2INDEX+2
;宏擴展
1MOVAX,ARRAY[(INDEX+2)*2]
心.宏注釋;;
在宏定義中,若注釋以一個分號開始
,則該注釋在宏擴展時出現(xiàn)。但若注釋以
兩個分號開始,則該注釋在宏擴展時不出
現(xiàn)。舉例見列表偽指令。
返回
6.4.5列表偽指令
格式功能
.LALL在列表文件中列出全部宏文本內(nèi)容
(以雙分號開頭的注釋除外)
.SALL在列表文件中不顯示任何宏文本內(nèi)容
,XALL(缺?。┰诹斜砦募兄涣谐隹僧a(chǎn)生
目標代碼的宏文本內(nèi)容
注意:這些列表偽指令只影響列表文件,并
不影響目標碼萌生成。一
6.5宏指令庫
為了使宏指令能讓多個程序共享,可以把它們
組織到一個文件中,并存放在磁盤上,把這種文件稱
為宏指令庫。
1.建立宏指令庫
可以把一些常用的宏指令集中在一個文件中形
成宏指令庫,用EDIT等任何文本編輯程序創(chuàng)建宏指令
庫,庫名由用戶自己起,而且對庫的擴展名沒有特殊
要求。庫中的宏指令以源代碼形式出現(xiàn)。
假設MACRO.LIB中包含以下宏指令(詳細內(nèi)容
見教材P174):
SETMODE;設置80*25彩色顯示模式
INCHAR;接收一個字符,并返回在AL中
OUTCHARX;輸出X字符
PUSHREG;保存寄存器DX、CX、BX、AX、DI、SI、BP
POPREG;恢復寄存器BP、SI、DI、AX、BX、CX、DX
WINDOWMACRO
Collor,WleftTopRow,WLeftTopCul,
WRightBottomRow,WRightBottomCuI
;功能:開窗口
MOVEMOCROX,Y;字型數(shù)據(jù)X送Y變量
CLRSCRN;清屏
CURSOR;置光標,入口參數(shù):口出口1_=行,列號
RETURN;返回操作系統(tǒng)
BIN_DECMACROASC,BlN
;功能:把16位二進制數(shù)轉(zhuǎn)換為十進制數(shù)的
;ASCII值,ASC為5個字節(jié)的十進制數(shù)緩沖區(qū)
;BIN為要轉(zhuǎn)換的二進制數(shù)。
DISPMACROASC
;顯示首址為ASC的字符串
2.把宏指令庫包含到應用程序中
格式:INCLUDE源文件名
功能:把另一個源文件包含到當前源文件中。
3.使用宏指令庫中的宏指令
例9.實現(xiàn)32位二進制數(shù)除以16位二進制數(shù),
并把結(jié)果用十進制數(shù)形式顯示在屏幕上。
編碼見程序6.9o
程序6.9
INCLUDEMACRO.LIB
PURGESETMODE,INCHAR,OUTCHAR,
WINDOW,MOVE,MUL
STACKSGSEGMENT
STACKSGENDS
DATASEGMENT
ADD7006652被除數(shù)
BDW1234除數(shù)
CDWQ商
PROMPTDB
ASCIIDB;轉(zhuǎn)換結(jié)果
DATAENDS
CODESEGMENT
ASSUME
CS:CODE,DS:DATA,SS:STACKSG
MAINPROCFAR
MOVAX,DATA
MOVDX,WORDPTRA+2
MOVAX,WORDPTRA
BIN_DECASCII,AX
CLRSCRN
DISPPROMPT
DISPASCII
RETURN
MAINENDP
CODEENDS
ENDMAIN
■-4.宏指令與子程序的區(qū)別
采用宏和子程序均能達到代碼共
享、簡化源程序的目的,但它們的區(qū)
別也是顯而易見的。區(qū)別主要有以下
幾點:
CT?工作方式的區(qū)別
(2)參數(shù)傳遞的方便性
(3)參數(shù)的多樣性及靈活性
通常:
?宏指令被用在代碼較短且參數(shù)
較多的場合;
?子程序被用在代碼較長的場合O
*6.6重復偽指令
當程序中需要重復書寫相同或幾乎相
同的語句時,可以用重復偽指令定義重復
塊,以簡化程序和減輕程序設計人員的工
作量。絕大部分MASM版本提供了REPT、
IRP和IRPC重復偽指令,而在MASM6.X中還
提供了其它重復偽指令。
6.6.1重復偽指令REPT
格式:
REPT
;重復塊
ENDM
匯編程序使重復塊的內(nèi)容重復多
次,重復次數(shù)由表達式給出。
說明:重復塊中可以出現(xiàn)任何有效的匯
編語句,數(shù)值表達式的計算結(jié)果應該是無符
號常數(shù)。
DATASEGMENT
TABLELABELWORD
REPT6;重復6次
DWX*X*X;定義立方值
X=X+1
ENDM
DATAENDS
匯編后的情況如下:
(1)0000DATASEGMENT
(2)0000TABLELABELWORD
(3)=0005X=5
REPT6
DWX*X*X
X=X+1
⑺ENDM
(8)0000007D1X*X*X
(9)000200D81X*X*X
(10)000401571X*X*X
(11)000602001X*X*X
(12)000802D91X*X*X
(13)000A03E81X*X*X
(14)000CDATAENDS
第(8)到第(13)行是匯編后的情況。在
MOVBX,10
REPT2
DECBX
ENDM
匯編后產(chǎn)生如下語句:
MOVBX,10
1DECBX
1DECBX
CHARSMACRONUM
MOVAH,2
CHAR='A'
REPTNUM
MOVDL,CHAR
INT21H
CHAR=CHAR+1
ENDM
ENDM
CODESEGMENT
ASSUMECS:CODE
MAINPROCFAR
CHARS26
MOVAX,4C00H
INT21H
MAINENDP
CODEENDS
ENDMAIN
從本例可以看出,重復偽指令可
以出現(xiàn)在宏指令中。
CHARSMACRONUM
MOVAH,2
CHAR='A'
REPTNUM
MOVDL,CHAR
INT21H
CHAR=CHAR+1
ENDM
ENDM
CODESEGMENT
ASSUMECS:CODE
OOOOMAINPROCFAR
CHARS26
0000B4021MOVAH,2
0002B2412MOVDL,CHAR;字符A
0004CD212INT21H
0006B2422MOVDL,CHAR;字符B
0008CD212INT21H
0066MOVDL,CHAR;字符Z
0068INT21H
006AB84C00AX,4C00H
006DINT21H
006FMAINENDP
006FCODEENDS
MAIN
IT:6.6.2不定重復偽指令
BRP偽指令
格式:
IRP形式參數(shù),(實參數(shù)〉
...;重復塊
ENDM
功能:匯編程序使重復塊的內(nèi)容重復多
次,重復次數(shù)由實參數(shù)個數(shù)決定。每次重復
都用尖括號中的一個實參數(shù)替代形式參數(shù),
依次使用實參數(shù),直到用完為止。
1.實參數(shù)可以是符號。
IRPREG,<AX,BX,CX,DX>
PUSHREG
ENDM
匯編后產(chǎn)生以下指令:
1PUSHAX
1PUSHBX
1PUSHCX
1PUSHDX
X,<1,2,3+5,'EDIT'》
DBX
ENDM
匯編后產(chǎn)生的,LST文件:
0000011DB1;數(shù)字
0001021DB2;數(shù)字
0002081DB3+5;常數(shù)表達式
0003454449541DB、EDI「;ASCII值
從目標碼部分可以看出,數(shù)字1、2生成01
、02,3+5計算后其值為8,,EDI「生成相應的
ASCII值45、44、49、54。
2.IRPC偽指令
冬格式:
IRPC形式參數(shù),數(shù)字串
;重復塊
ENDM
功能:匯編程序使重復塊的內(nèi)容重復多
次,重復次數(shù)由數(shù)字串中數(shù)字位數(shù)決定。每
次重復都用數(shù)字串中一個數(shù)字替代形參,依
次使用串中的數(shù)字,直到用完為止。
說明:重復塊中可以出現(xiàn)任何有效的匯
編語句。
,二例2.定義一串數(shù)字。
!RPCZ,1235
DBZ
ENDM
匯編后生成的.LST文件如下:
0001011DB1
0002021DB2
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞動合同勞務派遣合同
- IT系統(tǒng)開發(fā)與維護服務協(xié)議
- 互聯(lián)網(wǎng)醫(yī)院合作協(xié)議
- 合法的商品買賣合同
- 簽訂二手房買賣合同應注意的事項
- 項目總結(jié)報告及未來發(fā)展方向展望與分析
- 教育培訓行業(yè)在線課程服務合同
- 聯(lián)合采購協(xié)議書
- 基于用戶需求的移動支付應用創(chuàng)新方案設計
- 文化傳播項目投資合同
- 山東省海洋知識競賽(初中組)考試題及答案
- 藥品流通監(jiān)管培訓
- JD37-009-2024 山東省存量更新片區(qū)城市設計編制技術導則
- 《廣西高標準農(nóng)田耕地質(zhì)量評價工作 指導手冊》
- 幼兒園藝術領域活動設計
- 人教版四年級下冊數(shù)學全冊教案含反思
- 北京市海淀區(qū)重點中學2025屆高考數(shù)學押題試卷含解析
- 霧化吸入技術教學課件
- 2024EPC施工總包合同范本
- 上海市寶山區(qū)2024-2025學年高三一模英語試卷(含答案)
- 2024年神農(nóng)架林區(qū)林投集團招聘工作人員6名管理單位遴選500模擬題附帶答案詳解
評論
0/150
提交評論