第七章高級匯編語言技術(shù)_第1頁
第七章高級匯編語言技術(shù)_第2頁
第七章高級匯編語言技術(shù)_第3頁
第七章高級匯編語言技術(shù)_第4頁
第七章高級匯編語言技術(shù)_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

第七章高級匯編語言技術(shù)1、宏匯編2、重復(fù)匯編3、條件匯編如果在一個程序中多次使用同一組指令時,為了避免每次都要重寫,該如何解決?方法1:把這組指令寫成一個子程序,每次需要執(zhí)行時調(diào)用這個子程序就可以了。方法2:當(dāng)這組指令較短或不適合把它寫成一個子程序時,可以把它定義成一個宏,每次需要執(zhí)行時就去調(diào)用這個宏。宏匯編為用戶提供更加容易、更加靈活、更加向高級語言靠攏的匯編工具。宏:源程序中一段有獨立功能的程序代碼。宏指令:用戶自定義的指令。在編程時,將多次使用的功能用一條宏指令來代替。宏定義

macro_name

MACRO[啞元表];形參/虛參

……(宏定義體)……

ENDMmacro_name

宏指令名(宏名),調(diào)用時用。

[啞元表]形參表,啞元之間用逗號隔開一段有獨立功能的程序代碼宏調(diào)用格式:

macro_name[實元表];實參實元表中的實元與啞元表中的啞元在位置上一一對應(yīng);若實元數(shù)大于啞元數(shù),則多余的實元無效;若實元數(shù)小于啞元數(shù),則多余的啞元作“空(NUL)”處理;對宏指令的調(diào)用必須先定義后調(diào)用。注意:宏展開后,即用實參取代形式參數(shù)之后,所得到的語句應(yīng)該是有效的,否則匯編時會出錯。例1:用宏指令定義兩個字操作數(shù)相乘,得到一個16位的第三個操作數(shù)作為結(jié)果。宏定義:MULTIPLYMACROOPR1,OPR2,RESULT PUSHDX PUSHAX MOVAX,OPR1 IMULOPR2 MOVRESULT,AX POPAX POPDX ENDM宏調(diào)用:MULTIPLYCX,VAR,XYZ[BX]MULTIPLY240,BX,SAVE宏展開源程序被匯編時,匯編程序把宏調(diào)用展開,也就是用宏定義體取代源程序中的宏指令名,同時用實元取代啞元,所展開的指令前加上1表示這些宏指令是由宏展開而得到的較早的版本用+符號表示宏展開:1PUSHDX1 PUSHAX1 MOVAX,CX1 IMULVAR1 MOVXYZ[BX],AX1 POPAX1POPDX1PUSHDX1 PUSHAX1 MOVAX,2401 IMULBX1 MOVSAVE,AX1 POPAX1 POPDX宏調(diào)用與子程序調(diào)用的區(qū)別子程序:在程序執(zhí)行期間被調(diào)用,只占用自身大小的一段空間。主程序……CALLsub1……CALLsub1……CALLsub1……子程序sub1

………………ret宏調(diào)用:在匯編期間被展開,每調(diào)用一次就把宏定義體展開一次。宏定義宏調(diào)用宏展開Qmacrox,y

endm

……

QA,B

QC,D……

QE,F……

……

……

………………子程序與宏調(diào)用工作方式的差異1、子程序調(diào)用是在程序執(zhí)行期間進行的,主程序通過CALL指令轉(zhuǎn)入于程序的入口地址去執(zhí)行子程序,子程序執(zhí)行完后RET指令返回到主程序的調(diào)用處(斷點處);而宏調(diào)用是通過宏指令名和實在參數(shù)(如果有要傳遞的參數(shù)的話)進行調(diào)用的,而且是在匯編期間展開宏定義體的。2、子程序中的這組指令的機器碼在存儲器中只需要存放一次;而宏調(diào)用則不同,每調(diào)用一次就把宏定義體展開一次,因而它占有的存儲空間與調(diào)用次數(shù)有關(guān),調(diào)用次數(shù)越多則占有的存儲空間就越大3、子程序調(diào)用時需要用堆棧,調(diào)用子程序和返回主程序都要開銷必要的時間;而宏調(diào)用其宏定義體展開是插入在調(diào)用程序中,因此避免了調(diào)用時跳到宏和由宏返回所開銷的時間。如何選擇用子程序還是用宏調(diào)用呢?一般來說,由于宏匯編可能占用較大的空間,所以代碼較長的功能段往往使用子程序而不用宏匯編;而那些較短的且變元較多的功能段,則使用宏匯編比較合理。宏定義中的參數(shù)

1、可以無變元

2、可以是操作碼

3、可以是操作碼的一部分,但在宏定義體中必須用

&來分隔。

4、變元是ASCII串

5、%操作符宏定義可以無變元SAVEREGMACROPUSHAXPUSHBX PUSHCX PUSHDX PUSHSI PUSHDI ENDM變元可以是操作碼FOOMACROP1,P2,P3MOVAX,P1P2P3 ENDM宏調(diào)用:FOOWORD_VAR,INC,AX宏展開:1MOVAX,WORD_VAR1INCAX變元是操作碼的一部分變元可以是操作碼的一部分,但在宏定義體中必須用&作為分隔符。LEAPMACROCOND,LABJ&CONDLAB ENDM宏調(diào)用:LEAPZ,THERELEAPNZ,HERE宏展開:1JZTHERE1JNZHERE&是一個操作符,它在宏定義體中可以作為啞元的前綴,展開時可以把&前后兩個符號合并而形成一個符號,這個符號可以是操作碼、操作數(shù)或是一個字符串。例:FOMACROP1JMPTA&P1 ENDM宏調(diào)用:FOWORD_VAR宏展開:1JMPTAWORD_VAR如果宏定義寫為:FOMACROP1JMPTAP1 ENDM則在展開時,匯編程序把TAP1看作是一個獨立的標(biāo)號,并不把TAP1中的P1作為啞元看待,這樣就不能達(dá)到預(yù)期的結(jié)果。變元是ASCII串MSGGENMACROLAB,NUM,XYZLAB&NUMDB‘HELLOMR.&XYZ’ ENDM宏調(diào)用:MSGGENMSG,1,TAYLOR宏展開:1MSG1DB‘HELLOMR.TAYLOR’變元中使用%的情況其格式為%expression匯編程序把跟在%之后的表達(dá)式的值轉(zhuǎn)換成當(dāng)前基數(shù)下的數(shù),在展開期間,用這個數(shù)來取代啞元。MSGMACROCOUNT,STRINGMSG&COUNTDBSTRING ENDMERRMSGMACROTEXTCNTR=CNTR+1 MSG%CNTR,TEXT ENDM宏調(diào)用:CNTR=0ERRMSG‘SYNTAXERROR’ERRMSG‘INVALIDOPERAND’宏展開:2MSG1DB‘SYNTAXERROR’2MSG2DB‘INVALIDOPERAND’注意:2表示它是第二層展開的結(jié)果。一般在LST清單中,使用隱含的.XALL偽操作,即不產(chǎn)生代碼的語句在清單中并不列出。為了能看到宏展開后的所有語句,可以在源程序中增加.LALL語句。實際上,本例的展開可以分為如下兩層:CNTR=0CNTR=CNTR+11MSG%CNTR,’SYNTAXERROR’2MSG1DB‘SYNTAXERROR’1CNTR=CNTR+11MSG%CNTR,’INVALIDOPERAND’2MSG2DB‘INVALIDOPERAND’LOCAL偽操作在宏定義中允許使用標(biāo)號。如果在程序中多次使用該宏定義時。展開后會出現(xiàn)標(biāo)號的多重定義,這是不允許的。但是可以用偽指令LOCAL指定局部標(biāo)號。[格式]LOCAL局部標(biāo)號表

[說明]其中,局部標(biāo)號表中的各標(biāo)號之間用逗號分隔。匯編程序在匯編時對局部中標(biāo)號表中的各標(biāo)號建立唯一的符號(??0000一??FFFF)以取代展開后的各局部標(biāo)號。該偽指令必須是宏定義體中的第一個語句,而且在MACRO和LOCAL之間還不允許有注釋和分號標(biāo)志。宏定義體內(nèi)允許使用標(biāo)號,如ABSOLMACROOPERCMPOPER,0 JGENEXT NEGOPERNEXT: ENDM在宏定義中允許使用標(biāo)號。如果在程序中多次使用該宏定義時。展開后會出現(xiàn)標(biāo)號的多重定義,這是不允許的。但是可以用偽指令LOCAL指定局部標(biāo)號。本例中的ABSOL宏定義在考慮到有多次調(diào)用可能性的情況下,應(yīng)定義為:ABSOLMACROOPER LOCALNEXTCMPOPER,0 JGENEXT NEGOPERNEXT: ENDM宏調(diào)用:

ABSOLVAR ABSOLBX宏展開:1CMPOPER,01 JGE??00001 NEGOPER1??0000:…1CMPOPER,01 JGE??00011 NEGOPER1??0001:以上例子中,宏定義體內(nèi)只用了一個標(biāo)號,如果宏定義體內(nèi)的標(biāo)號數(shù)多于一個,則可以把它們列在LOCAL偽操作之后,如LOCALNEXT,OUT,EXIT在宏展開時,匯編程序?qū)Φ谝淮魏暾{(diào)用使用??0000取代NEXT,用??0001取代OUT,用??0002取代EXIT。對第二次宏調(diào)用將用??0003取代NEXT,用??0004取代OUT,用??0005取代EXIT。在宏定義體內(nèi)使用宏限制條件:必須先定義后調(diào)用在宏定義體內(nèi)不僅可以使用宏,也可以可以包含宏定義(也就是說,宏定義允許嵌套)例:

DIFMACROX,Y MOVAX,XSUBAX,Y ENDMDIFSQRMACROOPR1,OPR2,RESULT PUSHDX PUSHAX DIFOPR1,OPR2 IMULAX MOVRESULT,AX POPAX POPDXENDM宏調(diào)用:DIFSQRVAR1,VAR2,VAR3宏展開:1 PUSHDX1 PUSHAX2MOVAX,VAR12SUBAX,VAR21 IMULAX1 MOVVAR3,AX1 POPAX1 POPDXINT21MACROFUNCTN MOVAH,FUNCTN INT21H ENDMDISP MACROCHAR MOVDL,CHAR INT2102HENDM宏調(diào)用:

DISP’?’宏展開:1MOVDL,’?’2MOVAH,02H2INT21H宏定義體內(nèi)不僅可以使用宏調(diào)用,也可以包含宏定義。DEFMACMACROMACNAM,OPERATOR MACNAMMACROX,Y,Z PUSHAX MOVAX,X OPERATORAX,Y MOVZ,AX POPAX ENDM ENDM其中MACNAM是內(nèi)層的宏定義名,但又是外層宏定義的啞元。宏調(diào)用:DEFMACADDITION,ADD形成加法宏定義:

ADDITIONMACROX,Y,Z PUSHAX MOVAX,X ADDAX,Y MOVZ,AX POPAX ENDM同樣,宏調(diào)用:DEFMACSUBTRACT,SUB可以形成減法宏定義。DEFMACLOGOR,OR可以形成邏輯或宏定義。宏調(diào)用:ADDITIONVAR1,VAR2,VAR3展開成:1 PUSHAX1 MOVAX,VAR11 ADDAX,VAR21 MOVVAR3,AX1 POPAX列表偽操作功能:控制匯編清單中宏展開的列出情況源程序(ASM文件)經(jīng)匯編程序匯編,主要輸出是OBJ文件和LST文件(列表文件)。LST文件同時列出源程序和機器語言程序清單,并給出符號表。.XALL默認(rèn)值,只列出產(chǎn)生目標(biāo)碼的宏展開.LALL列出包括注釋在內(nèi)的所有宏展開.SALL不列出任何展開信息;;注釋;宏展開時,;;后面的注釋不予展開。例:源程序;definingandusingmacro-ex7_12_1Initzmacro;definemacroMov

ax,@data;initializesegmentMov

ds,ax;registerMov

es,axEndm;endmacroPromptmacromessge;definemacro;thismacrodisplaysanymessage;;generatescodethatlinkstodosMovah,09hLeadx,messge;promptInt21hEndm;endmacroFinishmacro;definemacroMovax,4c00hInt21hEndm;endmacro.modelsmall.386.stack200h;definestacksegment.data;definedatasegmentMessg1db‘customername?’,13,10,’$’Messg2db‘customeraddress?’,13,10,’$’.code;definecodesegmentBeginprocfar.sallInitz.xallPromptmessg1.lallPromptmessg2.xallFinishBeginendpEndbegin宏庫的建立與調(diào)用宏庫:只包含若干宏定義的文件,擴展名為MAC或LIB宏庫的調(diào)用:在程序的開始用INCLUDE語句說明,例如

INCLUDEC:\MACRO.MAC注:INCLUDE語句可以不放在程序的最前面,但必須放在所有的宏調(diào)用之前為上例建立的宏庫MACRO.MAC;alibraryofmacrosequencesmacro.macInitzmacro;definemacroMov

ax,@data;initializesegmentMov

ds,ax;registerMov

es,axEndm;endmacroPromptmacromessge;definemacro;thismacrodisplaysanymessage;;generatescodethatlinkstodosMovah,09hLeadx,messge;promptInt21hEndm;endmacroFinishmacro;definemacroMovax,4c00hInt21hEndm;endmacro使用宏庫情況下的例7.12程序?qū)崿F(xiàn)Includemacro.mac.modelsmall.386.stack200h;definestacksegment.data;definedatasegmentMessg1db‘customername?’,13,10,’$’Messg2db‘customeraddress?’,13,10,’$’.code;definecodesegmentBeginprocfarInitzPromptmessg1Promptmessg2FinishBeginendpEndbeginPURGE偽操作宏指令名可與指令助記符和偽指令名同名,但這時宏指令的優(yōu)先級最高,而同名的指令和偽操作便失效。偽指令PURGE可取消宏定義,恢復(fù)指令的原來功效。格式:PURGE宏指令名[,宏指令名,…]PURGE可取消多個宏定義,而各宏指令名之間應(yīng)以逗號分隔。功能:取消宏定義,使該宏定義為空。習(xí)題1:編寫一條宏指令CLRB,完成用空格符將一字符區(qū)中的字符取代的工作。字符區(qū)首地址及其長度為變元。CLRBMACRON,ARRAYCLD;設(shè)置方向標(biāo)志DF=0MOVCX,N;N為字符區(qū)長度MOVAL,20H;空格送AL寄存器LEADI,ARRAY;ARRAY為字符區(qū)首地址REPSTOSBENDM把AL的內(nèi)容存入由目的變址寄存器指向的附加段的某單元中,并根據(jù)DF的值及數(shù)據(jù)類型修改目的變址寄存器的內(nèi)容。當(dāng)它與REP聯(lián)用時,可把AL的內(nèi)容存入一個長度為COUNT的緩沖區(qū)中。2:某工廠計算周工資的方法是每小時的工資率RATE乘以工作時間HOUR,另外每工作滿十小時加獎金3元,工資總數(shù)存放在WAG中,請將月工資的計算編寫成一條宏指令WAGES,并展開宏調(diào)用:WAGESR1,42WAGESMACRORATE,HOURMOVAL,HOURMOVBL,RATEMULBLMOVCX,AXMOVAX,HOURMOVBL,10DIVBLANDAX,00FFHMOVBL,3MULBLADDCX,AXMOVWAG,CXENDM重復(fù)匯編在編寫匯編語言程序中,有時需要進行連續(xù)地重復(fù)完成相同的或幾乎完全相同的操作,這時可以使用重復(fù)匯編,使書寫的程序變得相當(dāng)簡潔。重復(fù)匯編有兩種格式重復(fù)偽操作不定重復(fù)偽操作重復(fù)偽操作格式 :REPT表達(dá)式

…. ENDM其中,REPT和ENDM為偽指令,它們必須成對出現(xiàn),中間是要重復(fù)的指令體,重復(fù)的次數(shù)由表達(dá)式的值來決定,表達(dá)式中如包含外部或未定義的項則匯編指示出錯。重復(fù)偽操作并不一定要用在宏定義體內(nèi)。例:7.13 X=0REPT10 X=X+1DBXENDM

匯編后產(chǎn)生

1DB1 1DB2 1DB3. 1DB10不定重復(fù)偽操作IRP偽操作格式: IRP形式參數(shù),<參數(shù)表>

…(指令體) ENDM其中,IRP和ENDM偽指令必須成對出現(xiàn),其間是要重復(fù)的指令體。重復(fù)的次數(shù)由參數(shù)表中參數(shù)的個數(shù)所決定,而且每重復(fù)一次,依次用參數(shù)表中的參數(shù)來代替形式參數(shù)。參數(shù)表必須用尖括號括起來,參數(shù)間用逗號分隔。例題:IRPX,<1,2,3,4,5,6,7,8,9,10>DBXENDM匯編后

1DB1 1DB2 . . 1DB10例題:IRPREG,<AX,BX,CX,DX>PUSH REGENDM匯編后

1 PUSH AX 1PUSH BX 1 PUSH CX 1 PUSH DXIRPC偽操作[格式] IRPC形式參數(shù),字符串(或<字符串>) …(指令體) ENDM[說明]其中,偽指令I(lǐng)RPC和ENDM必須成對出現(xiàn),其間是重復(fù)的指令體,重復(fù)的次數(shù)取決于字符串中字符的個數(shù),在每次重復(fù)時,依次用字符串的字符代替形式參數(shù)。例題:IRPCX,01234567DB X+1ENDM匯編后

1 DB1 1 DB2 . . 1 DB8例題:IRPCK,ABCDPUSH K&XENDM匯編后

1 PUSH AX 1PUSH BX 1 PUSH CX 1 PUSH DX條件匯編[格式] IFxxxx[<表達(dá)式>] …條件為真匯編此塊

[ELSE] …條件為假匯編此塊

ENDIF[說明]其中,IFxxxx表示條件偽操作命令,它必須與ENDIF相配對。匯編程序?qū)τ跅l件偽操作命令中給定的條件進行檢測,若條件成立(真),則匯編整個塊。如果其中有ELSE命令,當(dāng)條件成立時則只匯編從IFxxxx到ELSE之間的那一塊;當(dāng)條件不成立(假)時則只匯編從ELSE到ENDIF之間的那一塊。例:宏指令MAX把三個變元中的最大值放在AX中,而且使變元數(shù)不同時產(chǎn)生不同的程序段

MAXMARCOK,A,B,CLOCALNEXT,OUTMOVAX,AIFK-1IFK-2CMPC,AXJLENEXTMOVAX,CENDIFNEXT:CMPB,AXJLEOUTMOVAX,BENDIFOUT:ENDM宏調(diào)用:

MAX1,P MAX2,P,Q MAX3,P,Q,R宏展開:

MAX1,P 1MOVAX,P 1??0001: MAX2,P,Q 1MOVAX,P 1 ??0002: 1 CMPQ,AX 1 JLE??0003 1 MOVAX,Q 1 ??0003:MAX3,P,Q,R 1 MOV AX,P 1 CMP R,AX 1 JLE ??0004 1 MOV AX,R 1 ??0004: 1 CMP Q,AX 1 JLE ??0005 1 MOV AX,Q 1 ??0005:例: 宏指令BRANCH產(chǎn)生一條轉(zhuǎn)向X的轉(zhuǎn)移指令。當(dāng)它相對于X的距離小于128字節(jié)時產(chǎn)生JMPSHORTX;否則產(chǎn)生JMPNEARPTRX(X必須位于該轉(zhuǎn)移指令之后,即低地址區(qū))。

BRANCHMARCOXIF($-X)LT128JMPSHORTXELSEJMPNEARPTRXENDIF ENDM宏調(diào)用:BRANCHAA宏展開:1JMPSHORTAA否則產(chǎn)生

1JMP

NEARPTRAA

例:宏定義的遞歸調(diào)用,條件偽操作可以用來結(jié)束宏遞歸。宏指令POWER可以用來實現(xiàn)X和2N相乘,這只需對X左移N次即可實現(xiàn),可以設(shè)COUNT為遞歸次數(shù)的計數(shù)值,當(dāng)該數(shù)與N相等時就可以結(jié)束遞歸調(diào)用。宏定義:

POWERMARCOX,NSALX,1 COUNT=COUNT+1IFCOUNT-NPOWERX,NENDIFENDM宏調(diào)用:

COUNT=0 POWERAX,3宏展開:1 SALX,12 SALX,13 SALX,1條件偽操作IF1

條件偽操作IF1使用舉例例:仍使用“例7.12使用宏庫情況下的程序?qū)崿F(xiàn)”,但在INCLUDE語句前加上IF1,其含義是使INCLUDE語句只在匯編的第一遍掃視期間出現(xiàn),這樣宏庫的拷貝將不在匯編清單中出現(xiàn),以便節(jié)省空間If1Includemacro.macEndif.modelsmall.386.stack200h;definestacksegment.data;definedatasegmentMessg1db‘customername?’,13,10,’$’Messg2db‘customeraddress?’,13,10,’$’.code;definecodesegmentBeginprocfarInitzPromptmessg1Promptmessg2FinishBeginendpEndbegin條件偽操作IFNDEF使用舉例DIVIDE是一個用相繼的減法來實現(xiàn)除法的程序,在進入該程序主體之前,使用IFNDEF來檢查該宏定義的三個參數(shù)是否已在程序中得到定義,如其中任一參數(shù)未經(jīng)定義則將用CNTR加以記錄,最

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論