版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、會計學1 匯編語言程序設(shè)計第匯編語言程序設(shè)計第8章章 8.1 宏匯編 8.1.1 宏指令的定義、調(diào)用和展開 1宏定義偽指令 宏的概念與過程很相似,也是用一個宏名字來代替源程序中經(jīng)常需要用到的一個程序模塊(代碼段),宏定義語句格式與過程定義語句格式也相似。 格式: 宏名 MACRO 形式參數(shù)表 ;宏體 ENDM ;宏定義結(jié)束 功能:定義一個宏。 第1頁/共91頁 說明: 宏名必須是惟一的,它代表著所定義的宏體的內(nèi)容,在其后面的源程序中,可通過該名字來調(diào)用宏。 形式參數(shù)表是用逗號(或空格,或制表符)分隔的一個或多個形式參數(shù)。它是可選項。選用了形式參數(shù)時,所定義的宏稱為帶參數(shù)的宏。當調(diào)用宏時,需用對
2、應(yīng)的實際參數(shù)去取代,以實現(xiàn)向宏中傳遞信息。 第2頁/共91頁 宏體可以是匯編語言所允許的任意指令和偽指令語句序列,它決定了宏的功能。在宏體中還可以定義或調(diào)用另一個宏,這就是宏嵌套。 宏一經(jīng)定義,就像為指令系統(tǒng)增加了新的指令一樣,在程序中就可像指令一樣通過宏名對它進行任意次的調(diào)用,故又稱為宏指令或宏調(diào)用。要注意的是,宏定義必須放在第一條調(diào)用它的指令之前,一般都將它放在程序的開頭。 第3頁/共91頁 2宏的調(diào)用與展開 (1) 在匯編語言源程序中,為了使在源程序中不重復書寫需要多次使用的程序段,可以用一條宏指令來代替,由匯編程序在匯編時產(chǎn)生所需要的代碼。 例如,為了實現(xiàn)ASCII碼與BCD碼之間的相
3、互轉(zhuǎn)換,往往需要把AL中的內(nèi)容左移4位或右移4位,可以用80 x86的指令來實現(xiàn)。若要左移4位,可用: MOV CL,4 SAL AL,CL 第4頁/共91頁 若要多次使用,就可以用一條宏指令來代替,宏定義是: SHIFT MACRO MOV CL,4 SAL AL,CL ENDM 這樣,以后凡要使AL中的內(nèi)容左移4位,就可以用這條宏指令SHIFT來代替。 第5頁/共91頁 宏定義中,SHTFT是宏指令名,MACRO是宏定義的定義符,ENDM是宏定義的結(jié)束符,這兩者必須成對出現(xiàn)。 宏匯編一般由可執(zhí)行的指令語句和管理語句(即由偽指令構(gòu)成的語句)所構(gòu)成。經(jīng)宏定義后,就可以引用宏指令,這稱作宏調(diào)用。
4、宏匯編程序遇到這樣的調(diào)用時,就用對應(yīng)的宏體來代替這條宏指令,以產(chǎn)生目的代碼,這稱作宏展開。 第6頁/共91頁 (2) 宏定義不但能使源程序的書寫簡潔,而且由于宏指令具有接收參量的能力,所以功能就更靈活。 例如,上述的宏指令只能使AL中的內(nèi)容左移4位。若每次使用時,要移位的次數(shù)不同,或要使不同的寄存器移位,就不方便了。但是,若在宏定義中引入?yún)⒘浚涂梢詽M足上述要求。 第7頁/共91頁 例8-1 定義滿足不同移位次數(shù)要求的宏。 SHIFT MACRO X MOV CL,X SAL CL,CL ENDM 其中,X是一個形式參量(此處用來代表移位次數(shù))。在調(diào)用時可把實際要求的移位次數(shù)作為實在參量代入。
5、如 SHIFT 4 就可以用實在參量4代替在宏定義體中出現(xiàn)的形式參量X,從而實現(xiàn)左移4位的功能。 第8頁/共91頁 又如: SHIFT 6 就可以左移6次。這樣,就可以由調(diào)用時的實在參數(shù)來規(guī)定任意的移位次數(shù)。 第9頁/共91頁 例8-2 定義滿足使用不同寄存器實現(xiàn)移位要求的宏,可再引入一個形式參量Y。 SHIFT MACRO X,Y MOV CL,X SAL Y,CL ENDM 用形式參量Y來代替需要移位的寄存器。只要在調(diào)用時,把要移位的寄存器作為實在參量代入,就可以對任一個寄存器實現(xiàn)指定的左移次數(shù)。 SHIFT 4,AL SHIFT 4,BX SHIFT 6,DI 第10頁/共91頁 在匯編
6、這些宏指令時,分別產(chǎn)生以下指令語句,宏匯編程序在每一條由宏展開產(chǎn)生的指令前冠以加號“+”: +MOV CL,4 +SAL AL,CL +MOV CL,4 +SAL BX,CL +MOV CL,6 +SAL DI,CL 第一條宏指令使AL左移4位;第二條宏指令使16位寄存器BX左移4位;第三條宏指令使DI左移6位。 第11頁/共91頁 (3) 形式參量不僅可以出現(xiàn)在操作數(shù)部分,也可以出現(xiàn)在操作碼部分。 例8-3 用宏指令定義操作碼。 SHIFT MACRO X,Y,Z MOV CL,X S&Z Y,CL ENDM 其中第三個形式參量Z代替操作碼中的一部分。若在宏定義體中的形式參量沒有適當?shù)姆指舴?/p>
7、,則不被看作為形式參量,調(diào)用時也不被實在參量所代替。 第12頁/共91頁 例如,上例中的操作碼部分S&Z中,若Z與S之間沒有分隔,則此處的Z就不被看作形式參量。要定義它為形式參量,必須在其前面加上符號&。所以S&Z中Z就被看作是形式參量。若有以下調(diào)用: SHIFT 4,AL,AL SHIFT 6,BX,AR SHIFT 8,SI,HR 第13頁/共91頁 在匯編這些宏指令時,分別產(chǎn)生以下指令語句。 +MOV CL,4 +SAL AL,CL +MOV CL,6 +SAR BX,CL +MOV CL,8 +SHR SI,CL 這里的SHIFT宏指令可以對任一個寄存器進行任意的移位操作(算術(shù)左移、算
8、術(shù)右移、邏輯右移、可移任意指定的位數(shù))。 第14頁/共91頁 8.1.2 宏操作符 主要的宏操作偽指令有: 1) MACRO 格式: 宏指令名 MACRO ;宏體 ENDM 第15頁/共91頁 宏指令名是一個宏定義調(diào)用的依據(jù),也是不同宏定義相互區(qū)分的標志,是必須要有的。對于宏指令名的規(guī)定與對標識符的規(guī)定是一致的。宏定義中的形式參量表是任選的,可以沒有形式參量,也可以有若干形式參量。若有一個以上的形式參量時,它們之間必須用逗號分隔。對形式參量的規(guī)定與對標識符的規(guī)定是一致的。形式參量的個數(shù)沒有限制,只要一行限制在152個字符以內(nèi)就行。在調(diào)用時的實在參量多于1個時,也要用逗號分隔,它們與形式參量在順
9、序上相對應(yīng)。但IBM宏匯編并不要求它們在數(shù)量上必須一致。若調(diào)用時的實在參量多于形式參量,則多余的部分被忽略;若實在參量少于形式參量,則多余的形式參量變?yōu)镹ULL(空)。 第16頁/共91頁 2) PURGE 一個宏指令名,可以用偽指令PURGE來取消,然后就可以重新定義。 格式: PURGE 宏指令名, 功能:取消多個宏定義。 第17頁/共91頁 3) REPT 格式: REPT ;指令體 ENDM 功能:重復執(zhí)行在它的指令體部分所包含的語句。重復執(zhí)行的次數(shù),由表達式的值所決定。 第18頁/共91頁 例8-4 X=0 REPT 10 X=X+1 DB X ENDM 實現(xiàn)的功能是把1到10分配給
10、10個連續(xù)的內(nèi)存單元。 第19頁/共91頁 4) IRP 格式: IRP 形式參量, ;指令體 ENDM 功能:重復執(zhí)行指令體部分所包含的語句,重復的次數(shù)由參數(shù)表中的參數(shù)的個數(shù)決定(參數(shù)表中的參數(shù)必須用兩個尖括號括起來,參數(shù)間用逗號分隔),且每重復一次,依次用參數(shù)表中的參數(shù)來代替形式參量。 第20頁/共91頁 例8-5 IRP X, DB X ENDM 因為參數(shù)表中的參數(shù)個數(shù)為10,故指令體部分重復執(zhí)行10次。例8-4中的指令體部分只有一條偽指令DB X,其中X為形式參量。在第一次執(zhí)行時用參數(shù)表中的第一個參數(shù)1代替形式參量,就為DB 1;第二次執(zhí)行時,用參數(shù)表中的第二個參數(shù)2代替形式參量,就為
11、DB 2; 所以例8-4也是把1到10分配給10個連續(xù)的內(nèi)存單元。 第21頁/共91頁 5) IRPC 格式: IRPC 形式參量,字符串(或) ;指令體 ENDM 功能:重復執(zhí)行指令體部分所包含的語句。重復執(zhí)行的次數(shù),取決于字符串中的字符個數(shù),每次重復時,依次用字符串的字符代替形式參量。 IRPC偽指令與IRP偽指令很類似,只是用字符串(此字符串可以包括在兩個三角括號中,也可以不包括)代替了IRP指令中的參數(shù)表。 第22頁/共91頁 例8-6 IRPC X, DB X ENDM 實現(xiàn)的功能是:把字符A到F分配給內(nèi)存中的6個連續(xù)單元。 以上MACRO、REPT、IRP和IRPC 4個宏定義的偽
12、指令都必須以偽指令ENDM作為它的結(jié)束符。 第23頁/共91頁 有兩點需要特別指出: 宏定義也可以像程序設(shè)計語言中的標準函數(shù)一樣,構(gòu)成一個標準函數(shù)庫,供其他源程序使用。以文件的形式組織若干個宏定義即形成宏程序庫。程序設(shè)計中使用了宏程序庫中的宏定義時,在源程序中應(yīng)使用INCLUDE偽指令。宏匯編程序在匯編源程序時,當遇到該偽指令,就把INCLUDE偽指令所包含的宏程序庫中的文件掃描一遍,如同在程序中使用自己定義的宏一樣,在后面的程序中就可以對宏庫中的宏定義直接進行宏調(diào)用了。 第24頁/共91頁 與子程序一樣,宏定義也可以嵌套。宏定義的嵌套有兩種方式:宏定義嵌套和宏定義內(nèi)嵌套宏調(diào)用。在一個宏定義中
13、包含了另一個宏定義,則稱為宏定義嵌套;在一個宏定義的宏體內(nèi)有宏調(diào)用,則稱為宏定義內(nèi)嵌套宏調(diào)用。在宏定義內(nèi)嵌套宏調(diào)用中,被調(diào)用的宏指令必須是已定義的。宏定義嵌套常用于產(chǎn)生一些新的宏定義,而宏定義內(nèi)嵌套宏調(diào)用則可以使宏定義簡化,功能單一,便于通過組合的方法實現(xiàn)一個功能較為復雜的宏定義。 第25頁/共91頁 8.1.3 LOCAL偽指令 如果宏定義中含有變量名或標號,且在同一源程序中又多次被宏調(diào)用,那么宏匯編程序在宏展開時,產(chǎn)生多個相同的變量名或標號,這就不能滿足變量名和標號在同一程序中必須惟一的要求,從而產(chǎn)生匯編出錯,即產(chǎn)生“ERROR A2005:SYMBOL IS MULTIDEFINED”的
14、錯誤。為達到在宏定義中使用變量名和標號,又能避免這個錯誤的目的,可在宏定義中使用局部符號偽指令LOCAL對變量名或標號進行說明。 第26頁/共91頁 格式: LOCAL 功能:對在符號表中的每個符號,在匯編時每擴展一次便建立一個“?XXXX”惟一的符號,保證匯編時生成名字的惟一性。 說明: (1) 符號表是在宏定義中定義的變量名和標號,多個符號之間用逗號分隔。 (2) LOCAL偽指令指定的變量名和標號自動生成格式為“?XXXX”,符號的后四位順序使用0000FFFF的十六進制數(shù)字。 第27頁/共91頁 8.1.4 宏和過程的比較 宏和過程都可用來簡化源程序,并可使程序多次對它們進行調(diào)用,從而
15、使程序結(jié)構(gòu)簡潔清晰,符合結(jié)構(gòu)化程序設(shè)計風格。因此,對于那些需重復使用的程序模塊,既可用過程也可用宏來實現(xiàn)。 第28頁/共91頁 宏和過程的主要區(qū)別在于: (1) 宏操作可以直接傳遞和接收參數(shù),它不需通過棧等其他媒介來進行,因此編程比較容易。而過程不能直接帶有參數(shù),當過程之間需要傳遞參數(shù)時,必須通過棧、寄存器或存儲器來進行,所以相對于宏而言,它的編程要復雜一些。 第29頁/共91頁 (2) 宏調(diào)用只能簡化源程序的書寫,縮短源程序長度,它并沒有縮短目標代碼的長度,匯編程序處理宏指令時,是把宏體插入到宏調(diào)用處,所以目標程序占用內(nèi)存空間并不因宏操作而減少。而過程(子程序)調(diào)用卻能縮短目標程序的長度,因
16、為過程在源程序的目標代碼中只有一段,無論主程序調(diào)用多少次,除了增加CALL和RET指令的代碼外,并不增加子程序段代碼。 (3) 引入宏操作并不會在執(zhí)行目標代碼時增加額外的時間開銷。相反,過程調(diào)用由于需要保護和恢復現(xiàn)場及斷點,因而有額外的時間開銷,會延長目標程序的執(zhí)行時間。 第30頁/共91頁 若在一個源程序中多次調(diào)用一段程序,則可用子程序,也可以用宏指令來簡化源程序。用子程序的方法,匯編后產(chǎn)生的目標代碼少,即目標程序占用的內(nèi)存空間少,節(jié)約內(nèi)存空間。但是,子程序在執(zhí)行時,每調(diào)用一次都要先保護斷點,通常在程序中還要保護現(xiàn)場。同樣,在返回時,先要恢復現(xiàn)場,然后恢復斷點(返回)。這些操作都額外增加了時
17、間,因而執(zhí)行時間長,速度慢。而宏指令恰好相反,它的目標程序長,占用的內(nèi)存單元多,但在執(zhí)行時不需要保護斷點、現(xiàn)場以及恢復、返回等這些額外操作,因而執(zhí)行時間短,速度快。 第31頁/共91頁 所以,當要代替的程序段較短,速度是主要矛盾時,通常用宏指令。而當要代替的程序段較長,額外操作所附加的時間不明顯,節(jié)省存儲空間是主要矛盾時,通常用子程序。宏指令是機器的指令系統(tǒng)中沒有的,但又可以作為一條指令使用。所以,從形式上看,宏指令擴充了機器的指令系統(tǒng)。 第32頁/共91頁 8.2 重復匯編和條件匯編 8.2.1 重復匯編 在匯編程序設(shè)計中,經(jīng)常要連續(xù)地重復相同的或幾乎完全相同的代碼序列,這時可以使用重復偽指
18、令。 1重復偽指令 宏匯編語言提供的重復偽指令包括REPT、IRP、IRPC,其格式、功能及使用說明在8.1.2節(jié)中已講述,這里不再贅述。 第33頁/共91頁 2重復偽指令應(yīng)用舉例 例8-7 使用不同重復偽指令定義10個數(shù)據(jù),使其內(nèi)容分別為0,1,9。 第一種方法,使用REPT偽指令: COUNT0 REPT 10 DB COUNT COUNTCOUNT+1 ENDM 第34頁/共91頁 第二種方法,使用IRP偽指令: IRP X , DB X ENDM 第三種方法,使用IRPC偽指令: IRPC X 0123456789 DB X ENDM 第35頁/共91頁 以上三種方法具有同樣的功能,匯
19、編后產(chǎn)生的代碼如下: + DB 0 + DB 1 + DB 2 + DB 3 + DB 4 + DB 5 + DB 6 + DB 7 + DB 8 + DB 9 第36頁/共91頁 例8-8 下面兩條重復偽指令具有相同的功能。 (1) IRP指令: IRP REG, POP REG ENDM 第37頁/共91頁 (2) IRPC指令: IRPC R ABCD POP RX ENDM 匯編后它們產(chǎn)生的代碼如下: + POP AX + POP BX + POP CX + POP DX 第38頁/共91頁 8.2.2 條件匯編 條件匯編偽指令可使匯編程序根據(jù)某種條件對某部分源程序有選擇地進行匯編,在
20、形式上和高級語言中的條件語句類似,但實質(zhì)不同。條件匯編語句是一種說明性語句,其功能由匯編系統(tǒng)實現(xiàn);而一般高級語言的條件語句是執(zhí)行性語句,其功能由目標程序?qū)崿F(xiàn)。 條件匯編語句通常在宏定義中使用,使得宏定義的適用范圍更廣。一般情況下,使用條件匯編語句可使一個源文件產(chǎn)生幾個不同的源程序,它們可有不同的功能。 第39頁/共91頁 格式:IF 條件 語句序列1 ELSE 語句序列2 ENDIF 功能:當條件為真(滿足)時執(zhí)行匯編語句序列1,否則執(zhí)行匯編語句序列2。 第40頁/共91頁 說明:“條件”為IF偽指令說明符的一部分,ELSE偽指令及其后面的語句序列2是可選擇部分,表示條件為假(不滿足)時的情況
21、。如果屬于非完全分支的判斷,就不用這部分。整個條件匯編最后必須用ENDIF偽指令來結(jié)束。語句序列1和語句序列2中的語句是任意的,也可為條件匯編語句。 以下5組條件匯編開始語句均可選用ELSE語句,以便匯編條件為假時執(zhí)行語句序列2,但一個IF語句只能有一個ELSE與之對應(yīng)。 第41頁/共91頁 1) 是0否條件語句 語句有:IF和IFE。 IF語句。 格式:IF 表達式 功能:表達式值非0,則條件為真,執(zhí)行匯編語句序列1。 IFE語句。 格式:IFE 表達式 功能:表達式值為0,則條件為真,執(zhí)行匯編語句序列1。 第42頁/共91頁 2) 掃描1否條件語句 語句有:IF1和IF2。 IF1語句。
22、格式:IF1 功能:匯編處于第一次掃描時條件為真。 IF2語句。 格式:IF2 功能:匯編處于第二次掃描時條件為真。 第43頁/共91頁 3) 符號有定義否條件語句 語句有:IFDEF和IFNDEF。 IFDEF語句。 格式:IFDEF 符號 功能:符號已被定義或已由EXTRN偽指令說明,則條件為真。 IFNDEF語句。 格式:IFNDEF 符號 功能:符號未被定義或未由EXTRN偽指令說明,則條件為真。 第44頁/共91頁 4) 空否條件語句 語句有:IFB和IFNB。 IFB語句。 格式:IFB 功能:參數(shù)為空格,則條件為真。尖括號不能省略。 IFNB語句 格式:IFNB 功能:參數(shù)不為空
23、格,則條件為真。尖括號不能省略。 第45頁/共91頁 5) 字符串比較條件語句 語句有:IFIDN和IFDEF。 IFIDN語句。 格式:IFIDN , 功能:字符串1與字符串2相同,則條件為真。 第46頁/共91頁 IFDIF語句 格式:IFDIF , 功能:字符串1與字符串2不相同,則條件為真。 說明:這兩條語句只能在宏定義中使用,檢查傳送給兩個參數(shù)的實參是否相同。 例8-9 將輸入及輸出字符的DOS功能調(diào)用放在一個宏定義中,通過判斷參數(shù)為0還是非0值來選擇是執(zhí)行匯編輸入還是輸出的DOS功能。 第47頁/共91頁 所編制的程序描述如下,其中含有條件匯編的語句。 INOUTMACRO X I
24、F X MOV AH,2 INT 21H ;輸出DL中的字符 ELSE MOV AH,1 INT 21H ;輸入一個字符到AL ENDIF ENDM 第48頁/共91頁 當宏調(diào)用為INOUT 0時,表明傳遞給參數(shù)X的值為0,此時IF X的條件為假,因此匯編程序只匯編ELSE與ENDIF之間的語句,這樣,對該宏調(diào)用來說,實際上是執(zhí)行下面的兩條指令: MOV AH,1 INT 21H 而當宏調(diào)用為INOUT 1時,實際上是執(zhí)行這樣兩條指令: MOV AH,2 INT 21H 第49頁/共91頁 8.3 匯編語言與高級語言的混合編程 8.3.1 調(diào)用協(xié)議 匯編程序和匯編語言常常以在線匯編語言代碼的形
25、式,通過過程同高級語言,如C/C+、BACIC、PASCAL及FORTRAN一起使用。需要指出的是,這里盡管講的是使用Microsoft匯編語言過程,但只要提供兼容的調(diào)用協(xié)議,大多數(shù)其他語言也能夠使用。 在與高級語言接口時,匯編程序使用兩種調(diào)用協(xié)議:一是用于C/C+語言的C語言調(diào)用協(xié)議,二是用于BASIC、PASCAL和FORTRAN語言的PASCAL語言調(diào)用協(xié)議。調(diào)用協(xié)議語言在MODEL語句中或與PROC語句相聯(lián)系的OPTION指示符中指定。除用這些語句以外還可以用完全段定義指定。 第50頁/共91頁 1C語言調(diào)用協(xié)議 C語言調(diào)用協(xié)議從右到左壓入?yún)?shù),像它們在參數(shù)表里放的那樣,帶著放在棧上的
26、參數(shù)從匯編語言過程返回,返回結(jié)果或者放在AX中或者放在DX AX中。在BP、DI、SI、DS、SS和方向標志位被改動之前應(yīng)使用匯編語言過程保存起來。這些寄存器是高級語言能用到的。圖8-1給出了C語言調(diào)用協(xié)議下近調(diào)用和遠調(diào)用的棧。 第51頁/共91頁 圖8-1 使用C語言調(diào)用協(xié)議時的棧內(nèi)容 (a) 近程調(diào)用;(b) 遠程調(diào)用 參數(shù)2 參數(shù)1 IP(返回地址)(SP) 存儲器 (a) 參數(shù)2 參數(shù)1 IP(返回地址)(SP) 存儲器 (b) CS(返回地址) 第52頁/共91頁 對棧內(nèi)參數(shù)的訪問由C語言調(diào)用協(xié)議提供,如例8-10所示。帶*號的語句是匯編程序加上的,以保持與C語言調(diào)用協(xié)議的一致。注意
27、搞清楚BP的內(nèi)容如何被壓入棧中,以及BP是如何被裝入SP值以訪問由C語言程序放在棧中的參數(shù)這兩個問題。 第53頁/共91頁 例8-10 .LISTALL .MODEL SMALL,C SSS PROTO C,A:SWORD,A:SWORD .CODE SSS PROC C,A:SWORD,B:SWORD PUSH BP ;保存BP MOV BP,SP ;棧地址存入BP MOV AX,A ;使用參數(shù)A ADD AX,B ;使用參數(shù)B POP BP ;恢復BP RET 00000H SSS ENDP END 第54頁/共91頁 根據(jù)C語言調(diào)用協(xié)議編寫的匯編語言過程通過指令I(lǐng)NVOKE而被調(diào)用。IN
28、VOKE用來替代標準的CALL指令。INVOKE遵循C語言調(diào)用協(xié)議,允許匯編語言程序訪問C語言程序和函數(shù)。INVOKE指令被用來訪問例8-10中的過程,例如,INVOKE SSS,20,30實現(xiàn)把30加上20后,結(jié)果放入AX中并返回。INVOKE與CALL的不同之處,按照調(diào)用協(xié)議的要求,INVOKE指令必須將參數(shù)從棧中全部移出。INVOKE指令的語法要求過程名后必須跟著全部的參數(shù),參數(shù)間用逗號隔開。 第55頁/共91頁 2INVOKE指令的使用 用 PUSH把參數(shù)壓入堆棧,如果不小心把參數(shù)個數(shù)搞錯了,就會使堆棧不平衡,從而使程序從堆棧中取出錯誤的返回地址,引起不可預(yù)料的后果。所以有必要用一條語
29、句來完成自動檢驗的任務(wù)。INVOKE語句是能自動將所有的參數(shù)壓入棧中,并檢測參數(shù)個數(shù)、類型是否正確,使用 CALL來調(diào)用的一個宏指令。 INVOKE在匯編程序中調(diào)用子程序時,其參數(shù)的傳遞是通過堆棧來進行的。例如,MessageBox()函數(shù)在USER32.INC文件中是這樣聲明的: MESSAGEBOX(HWND HWND,LPCTSTR LPTEXT,LPCTSTR LPCAPTION,UINT UTYPE), 第56頁/共91頁 在匯編程序中可這樣調(diào)用它: PUSH UTYPE PUSH LPCAPTION PUSH LPTEXT PUSH HWND CALL MessageBox PUS
30、H為匯編語言中的進棧指令。上面語句的原理是先將函數(shù)所需要的參數(shù),壓入到堆棧中去,然后再用CALL指令來調(diào)用該函數(shù)。 第57頁/共91頁 需要注意的是,在上述的參數(shù)進棧過程中,是從左到右依次壓入的,即最右面的參數(shù)是最后一個進堆棧,采用的是PASCAL規(guī)則。引入INVOKE語句后,就可自動的將所調(diào)用子程序中的參數(shù)壓入堆棧中,而無須編程者用手工壓入。所以上面的代碼就可以變?yōu)?INVOKE MessageBox,NULL,addr szText,addr szCaption,MB_OK。 addr是用來把變量參數(shù)的地址傳遞給被調(diào)用的函數(shù)(注意,是所指變量在內(nèi)存中的地址,而不是變量中的值),它只能在IN
31、VOKE語句中使用。 第58頁/共91頁 3PASCAL語言調(diào)用協(xié)議 PASCAL語言調(diào)用協(xié)議用于BASIC、PASCAL和FORTRAN語言,在WINDOWS中,它也被用于訪問WINDOWS庫文件(WINH.LIB)中的函數(shù)。PASCAL語言調(diào)用協(xié)議與C語言調(diào)用協(xié)議的差異在于:參數(shù)是自左至右壓入棧中。如果用在匯編語言過程中時,PASCAL語言調(diào)用協(xié)議也需要保存寄存器SI、DI、DS和SS的內(nèi)容。方向標志位在登錄時要被清零,并以清除狀態(tài)被返回。和在C語言調(diào)用協(xié)議中一樣,INVOKE語句也用于由匯編語言進出高級語言過程。 第59頁/共91頁 這一點在匯編語言同WINDOWS一起使用時格外重要,以
32、INVOKE MessageBeep,-1為例,如果WINH.LIB庫文件已被程序裝載,則該指令使揚聲器發(fā)出“嘀”的一聲。其他參數(shù)也可與MessageBeep一起使用,從而由WINDOWS發(fā)出各種失敗提示音。在C語言程序中,通過在C語言程序的開頭使用指令#INCLUDE ,就可以訪問WINDOWS應(yīng)用程序接口(API)。 第60頁/共91頁 圖8-2 使用PASCAL語言調(diào)用協(xié)議時棧內(nèi)容 參數(shù)1 參數(shù)2 IP(返回地址) (BP) 存儲器 CS(返回地址) BP 第61頁/共91頁 圖8-2給出了從PASCAL中調(diào)用函數(shù)時的棧,注意:所有這些語言調(diào)用的函數(shù)都被認為是遠程調(diào)用,BP給出了存儲參數(shù)
33、的棧的地址。最右邊的參數(shù)的地址為BP+6,這一點與C語言調(diào)用協(xié)議正好相反。同C語言調(diào)用協(xié)議一樣,隱蔽的指令將BP壓入棧,并將SP寫入BP。 第62頁/共91頁 4數(shù)據(jù)類型 表8-1 各種數(shù)據(jù)類型的比較 MASM數(shù)據(jù)類型C語言數(shù)據(jù)類型PASCAL數(shù)據(jù)類型 BYTEunsigned char SBYTEchar WORDunsigned shortSTRING*1 SWORDshort int INTEGER DWORDunsigned long SDWORDlongLONG(&) REAL4floatSINGLE(!) REAL8doubleDOUBLE(#) REAL10long double
34、 第63頁/共91頁 8.3.2 與C語言的接口 例8-11 本例給出了一個被C語言程序調(diào)用的過程,該過程使用MODEL語句指示內(nèi)存模型(本例為小模型)和相應(yīng)的調(diào)用協(xié)議語言(C語言)。PROTO語句把本過程作為外部函數(shù)聲明,并指定了全部與本過程相關(guān)的參數(shù)的大小和名稱。本過程被作為一個近程調(diào)用 .MODEL SMALL,C X1 PROTO C,l:SWORD,F(xiàn):SWORD .CODE 第64頁/共91頁 X1 PROC C,l:SWORD,LSWORD FILDPI ;取出 FADD ST,ST(0) ;計算2pi MOV AX,1 ;取1 MOV TEMP,AX FILD TEMP ;取l
35、 FMUL ;計算2pil MOV AX,F(xiàn) ;取F MOV TEMP,AX FILD TEMP ;取F FMUL ;計算2pilf FISTP TEMP ;保存結(jié)果 第65頁/共91頁 MOV AX,TEMP ;取結(jié)果用以返回C RET X1 ENDP TEMP DW ? ;暫存區(qū) END 第66頁/共91頁 本過程使用數(shù)值協(xié)處理器計算電抗值,使用公式X1=2lF。其中,參數(shù)F和l從C語言程序中傳送到匯編語言過程中,返回值(X1)作為一個字長的整型變量由AX傳回C語言程序。通過BP+4和BP+6給出的地址,可以從棧中取出l和F的數(shù)據(jù)。本例中的MOV AX,l指令,若轉(zhuǎn)換為代碼應(yīng)為MOV AX
36、,BP+4,通過該指令可從棧中取出l值。 第67頁/共91頁 例8-12 本例給出了主模塊的C語言調(diào)用順序,該程序順序打印出電感系數(shù)為4H,頻率為1000 Hz的電抗值。注意:本程序中的計算結(jié)果被變換為整型。 #include extern int xl(int l,int f); void main() printf(The inductive reactance of 4 H at 1000 Hz isdn,xl(4,1000); 第68頁/共91頁 8.3.3 與PASCAL語言的接口 1有關(guān)的PASCAL語句和調(diào)用約定 PASCAL語言沒有提供CALL調(diào)用語句。PASCAL主程序?qū)R編
37、語言子程序的調(diào)用是通過外部過程和外部函數(shù)調(diào)用的形式來實現(xiàn)的。為了保證調(diào)用的正確實施,PASCAL主程序和被調(diào)用的匯編語言子程序都要遵從一定的調(diào)用約定。PASCAL語言中的過程和函數(shù)有所不同。 第69頁/共91頁 1) 過程方式 在PASCAL程序中,對要調(diào)用的匯編語言過程必須預(yù)先采用PROCEDURE說明語句加以定義說明。PROCEDURE語句的格式為: PROCEDURE過程名(參數(shù)表):過程屬性; 這樣,PROCEDURE語句將向PASCAL編譯程序提供如下信息: (1) 被調(diào)用的過程名; (2) 此過程是內(nèi)部過程還是外部過程; (3) 過程的參數(shù)名和類型; (4) 是“數(shù)值參數(shù)”還是“引
38、用參數(shù)”。 第70頁/共91頁 由于匯編語言子程序是單獨編寫和匯編的,它相對PASCAL主程序而言總是外部的。所以,其“過程屬性”為EXTERN。并且,過程名必須在匯編語言程序中用PUBLIC偽指令加以說明。第(3)項的過程參數(shù)名和類型是符合PASCAL要求的變量標識符和數(shù)據(jù)類型。在進行PASCAL過程調(diào)用時,過程參數(shù)也是通過棧來進行傳遞的。第(4)項的“數(shù)值參數(shù)”和“引用參數(shù)”涉及到是傳遞參數(shù)變量值,還是傳遞參數(shù)變量地址的問題。當一個變量是數(shù)值參數(shù)時,主程序把此變量的值入棧,即傳遞給被調(diào)用過程;否則,主程序把此變量的地址入棧。作為引用參數(shù)的變量,在PROCEDURE語句中須用VAR或VARS
39、來加以說明。兩者的區(qū)別在于:對由VAR說明的參數(shù),主程序須將其變量地址的偏移量入棧;而對由VARS說明的參數(shù),除變量地址的偏移量外,主程序還要將此變量地址的段地址入棧。語句: 第71頁/共91頁 PROCEDURE ADDP(A,B:INTEGER;VAR C:INTEGER):EXTERN; 定義了一個有3個參數(shù)的外部過程ADDP。其中,變量A和B是整型數(shù)值參數(shù),而變量C是整型引用參數(shù);一旦匯編語言過程在PASCAL主程序中經(jīng)由PROCEDURE語句定義說明后,PASCAL主程序就可以采用相應(yīng)的過程調(diào)用語句來調(diào)用此匯編語言過程了,過程調(diào)用語句的格式為 過程名(參數(shù)表) 對上面的ADDP過程,
40、其相應(yīng)的過程調(diào)用語句為 ADDP(A,B,C) 其中,A,B,C是PASCAL主程序中的整型變量。 第72頁/共91頁 在被調(diào)用的匯編語言子程序中,PASCAL對過程的要求是: (1) 由于寄存器SP不能用于一般的尋址方式,通常用BP來存取傳遞的調(diào)用參數(shù)。所以,在過程程序開始時要先把BP的原有內(nèi)容入棧保存,并在返回PASCAL主程序之前恢復內(nèi)容。另外,若要在子程序中改變DS和SS等寄存器的內(nèi)容,也須加以保存和恢復。 (2) 由于是外部過程,在返回PASCAL主程序時應(yīng)采用長返回指令,即進行段間返回。 (3) 在返回時,應(yīng)取消棧參數(shù),即主程序傳遞給此過程的所有調(diào)用參數(shù)。 第73頁/共91頁 下面
41、是用匯編語言編寫的ADDP過程程序,在程序中,PUBLIC指令將過程名ADDP存放。 CODE SEGMENT ASSUME CS CODE ADDP PROC FAR PUBLIC ADDP PUSH BP MOV BP,SP PUSH AX 第74頁/共91頁 PUSH BX MOV AX,BP+10 ADD AX,BP+8 MOV BXBP+6 MOV BX,AX POP BX POP AX POP BP RET 6 ADDP ENDP 第75頁/共91頁 過程的FAR屬性使得后面的RET指令成為長返回指令。RET指令中的整數(shù)用于消去棧參數(shù),它在返回后將自動加入到SP寄存器中。程序的“R
42、ET 6”指令執(zhí)行前后棧內(nèi)容的變化如圖8-3所示。 當ADDP過程的C變量為VARS引用參數(shù)時,相應(yīng)的匯編語言程序有所不同。由于C的段地址,A和B的地址由BP+10和BP+8變?yōu)锽P+12和BP+10。同時,“RET 6”變?yōu)椤癛ET 8”。除此之外,由于C變量不是當前DS寄存器所指數(shù)據(jù)段中的變量,對它的存取方式也與前不同,如圖8-4所示。 第76頁/共91頁 圖8-3 棧變化 (SP) A的內(nèi)容 C的偏移量 返回段地址CS B的內(nèi)容 返回偏移量IP 6 XXXXX 執(zhí)行“RET 6” (SP)XXXXX 第77頁/共91頁 圖8-4 C變量為VARS引用參數(shù)時的堆棧結(jié)構(gòu) (SP) A的內(nèi)容
43、C的偏移量 CS IP B的內(nèi)容 第78頁/共91頁 CODE SEGMENT ASSUME CS CODE ADDP PROC FAR PUBLIC ADDP PUSH BP MOV BP,SP PUSH AX PUSH BX PUSH ES MOV AX,BP+12 第79頁/共91頁 ADD AX,BP+10 LES BX, BP+6 MOV ES BX,AX POP ES POP BX POP AX POP BP RET 8 ADDP ENDP CODE ENDS END 第80頁/共91頁 2) 函數(shù)方式 函數(shù)方式同過程方式很相似。在PASCAL程序中,對要調(diào)用的匯編函數(shù)也必須預(yù)先加以說明。不過,此時采用的是FUNCTION說明語句,而不是PROCEDURE說明語句。 FUNCTION語句的格式為 FUNCTION 函數(shù)名(參數(shù)表):函數(shù)類型;函數(shù)屬性; 在FUNCTION語句中,除增加了一個“函數(shù)類型”外,其余同PROCEDURE語句一樣。“函數(shù)類型”符合PASCAL要求的數(shù)據(jù)類型的語句。如: FUNCTION ADDF(A,B:INTEGER):INTEGER:EXTERN; 說明定義了一個名為ADDF的外
溫馨提示
- 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)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《自適應(yīng)控》復習提綱(知識點)
- 店面分租合同范本
- 拆裝廠房電纜合同范例
- 小泵車租用合同范例
- 工程汽車租賃合同范例
- 關(guān)于承攬服務(wù)合同范例
- 承接工程臨建合同范例
- 寫字樓 空調(diào) 合同范例
- 二手房貸款網(wǎng)簽合同范例
- 公司股質(zhì)押合同范例
- GB/T 10325-2012定形耐火制品驗收抽樣檢驗規(guī)則
- 中考數(shù)學真題變式題庫
- FZ/T 91019-1998染整機械導布輥制造工藝規(guī)范
- FZ/T 52025-2012再生有色滌綸短纖維
- SHSG0522003 石油化工裝置工藝設(shè)計包(成套技術(shù))內(nèi)容規(guī)定
- FMEA-培訓教材-汽車fmea培訓課件
- 制造部年終總結(jié)報告課件
- 粵科版高中通用技術(shù)選修1:電子控制技術(shù)全套課件
- 知識產(chǎn)權(quán)法(英文) Intellectual Property Right Law課件
- 熱力管道焊接技術(shù)交底記錄大全
- 接地裝置安裝試驗記錄
評論
0/150
提交評論