第8章 高級(jí)匯編技術(shù)_第1頁
第8章 高級(jí)匯編技術(shù)_第2頁
第8章 高級(jí)匯編技術(shù)_第3頁
第8章 高級(jí)匯編技術(shù)_第4頁
第8章 高級(jí)匯編技術(shù)_第5頁
已閱讀5頁,還剩86頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

依第『章富」匯編技術(shù)

第3章布被匯編技木

8.1宏匯編

8.2重復(fù)匯編和條件匯編

8.3匯編語言與高級(jí)語言的混合編程

8.1宏匯編w

8.1.1宏指令的定義、調(diào)用和展開

1.宏定義偽指令

宏的概念與過程很相似,也是用一個(gè)宏名字來代替源程序中

經(jīng)常需要用到的一個(gè)程序模塊(代碼段),宏定義語句格式與過程

定義語句格式也相似。

格式:

宏名MACRO[形式參數(shù)表]

;;宏體

ENDM;宏定義結(jié)束

功能:定義一個(gè)宏。

依第』章卷級(jí)匯編技術(shù)圖£

說明:

①宏名必須是惟一的,它代表著所定義的宏體的內(nèi)容,在

其后面的源程序中,可通過該名字來調(diào)用宏。

②形式參數(shù)表是用逗號(hào)(或空格,或制表符)分隔的一個(gè)或

多個(gè)形式參數(shù)。它是可選項(xiàng)。選用了形式參數(shù)時(shí),所定義的宏

稱為帶參數(shù)的宏。當(dāng)調(diào)用宏時(shí),需用對(duì)應(yīng)的實(shí)際參數(shù)去取代,

以實(shí)現(xiàn)向宏中傳遞信息。

③宏體可以是匯編語言所允許的任意指令和偽指令語句序

列,它決定了宏的功能。在宏體中還可以定義或調(diào)用另一個(gè)宏,

這就是宏嵌套。

④宏一經(jīng)定義,就像為指令系統(tǒng)增加了新的指令一樣,在

程序中就可像指令一樣通過宏名對(duì)它進(jìn)行任意次的調(diào)用,故又稱

為宏指令或宏調(diào)用。要注意的是,宏定義必須放在第一條調(diào)用它

的指令之前,一般都將它放在程序的開頭。

2.宏的調(diào)用與展開

(1)在匯編語言源程序中,為了使在源程序中不重復(fù)書寫需

要多次使用的程序段,可以用一條宏指令來代替,由匯編程序

在匯編時(shí)產(chǎn)生所需要的代碼。

例如,為了實(shí)現(xiàn)ASCII碼與BCD碼之間的相互轉(zhuǎn)換,往往需

要把AL中的內(nèi)容左移4位或右移4位,可以用80x86的指令來實(shí)現(xiàn)。

若要左移4位,可用:

MOVCL,4

SALAL,CL

若要多次使用,就可以用一條宏指令來代替,宏定義是:

SHIFTMACRO

MOVCL,4

SALAL,CL

ENDM

這樣,以后凡要使AL中的內(nèi)容左移4位,就可以用這條宏

指令SHIFT來代替。

―二FF-

宏定義中,SHTFT是宏指令名,MACRO是宏定義的定義

符,ENDM是宏定義的結(jié)束符,這兩者必須成對(duì)出現(xiàn)。

宏匯編一般由可執(zhí)行的指令語句和管理語句(即由偽指令構(gòu)

成的語句)所構(gòu)成。經(jīng)宏定義后,就可以引用宏指令,這稱作宏

調(diào)用。宏匯編程序遇到這樣的調(diào)用時(shí),就用對(duì)應(yīng)的宏體來代替

這條宏指令,以產(chǎn)生目的代碼,這稱作宏展開。

(2)宏定義不但能使源程序的書寫簡潔,而且由于宏指令具

有接收參量的能力,所以功能就更靈活。

例如,上述的宏指令只能使AL中的內(nèi)容左移4位。若每次使

用時(shí),要移位的次數(shù)不同,或要使不同的寄存器移位,就不方便

了。但是,若在宏定義中引入?yún)⒘?,就可以滿足上述要求。

例8?1定義滿足不同移位次數(shù)要求的宏。

SHIFTMACROX

MOVCL,X

SALCL,CL

ENDM

其中,X是一個(gè)形式參量(此處用來代表移位次數(shù))。在調(diào)用時(shí)可

把實(shí)際要求的移位次數(shù)作為實(shí)在參量代入。如

SHIFT4

就可以用實(shí)在參量4代替在宏定義體中出現(xiàn)的形式參量X,從而

實(shí)現(xiàn)左移4位的功能。

依第『章富」匯編技術(shù)

又如:

SHIFT6

就可以左移6次。這樣,就可以由調(diào)用時(shí)的實(shí)在參數(shù)來規(guī)定任意

的移位次數(shù)。

-Jc

£人第8章富像匯編技術(shù)血

例8-2定義滿足使用不同寄存器實(shí)現(xiàn)移位要求的宏,可

入一個(gè)形式參量Y。

SHIFTMACROX,Y

MOVCL,X

SALY,CL

ENDM

用形式參量Y來代替需要移位的寄存器。只要在調(diào)用時(shí),把要移

位的寄存器作為實(shí)在參量代入,就可以對(duì)任一個(gè)寄存器實(shí)現(xiàn)指

定的左移次數(shù)。

SHIFT4,AL

SHIFT4,BX

£三第9章富像匯編技術(shù)

在匯編這些宏指令時(shí),分別產(chǎn)生以下指令語句,宏匯編

序在每一條由宏展開產(chǎn)生的指令前冠以加號(hào)“+”:

+MOVCL,4

+SALAL,CL

+MOVCL,4

+SALBX,CL

+MOVCL,6

+SALDLCL

第一條宏指令使AL左移4位;第二條宏指令使16位寄存器

BX左移4位;第三條宏指令使DI左移6位。

Ml

(3)形式參量不僅可以出現(xiàn)在操作數(shù)部分,也可以出現(xiàn)在操

作碼部分。

例8-3用宏指令定義操作碼。

SHIFTMACROX,Y,Z

MOVCL,X

S&ZY,CL

ENDM

其中第三個(gè)形式參量Z代替操作碼中的一部分。若在宏定義

體中的形式參量沒有適當(dāng)?shù)姆指舴?,則不被看作為形式參量,

調(diào)用時(shí)也不被實(shí)在參量所代替。

例如,上例中的操作碼部分S&Z中,若Z與S之間沒有分隔,

則此處的Z就不被看作形式參量。要定義它為形式參量,必須在

其前面加上符號(hào)所以S&Z中Z就被看作是形式參量。若有以

下調(diào)用:

SHIFT4,AL,AL

SHIFT6,BX,AR

SHIFT8,SLHR

在匯編這些宏指令時(shí),分別產(chǎn)生以下指令語句。

+MOVCL,4

+SALAL,CL

+MOVCL,6

+SARBX,CL

+MOVCL,8

+SHRSLCL

這里的SHIFT宏指令可以對(duì)任一個(gè)寄存器進(jìn)行任意的移位

操作(算術(shù)左移、算術(shù)右移、邏輯右移、可移任意指定的位數(shù))。

?一一“一JUh一

依第『章富」匯編技術(shù)

8.1.2宏操作符

主要的宏操作偽指令有:

1)MACRO

格式:

宏指令名MACRO〈形式參量表>

;宏體

ENDM

心孚章富像匯編技術(shù)衣£

宏指令名是-個(gè)宏定義調(diào)用的依據(jù),也是不同宏定義方

分的標(biāo)志,是必須要有的。對(duì)于宏指令名的規(guī)定與對(duì)標(biāo)識(shí)符的規(guī)

定是一致的。宏定義中的形式參量表是任選的,可以沒有形式參

量,也可以有若干形式參量。若有一個(gè)以上的形式參量時(shí),它們

之間必須用逗號(hào)分隔。對(duì)形式參量的規(guī)定與對(duì)標(biāo)識(shí)符的規(guī)定是一

致的。形式參量的個(gè)數(shù)沒有限制,只要一行限制在152個(gè)字符以

內(nèi)就行。在調(diào)用時(shí)的實(shí)在參量多于1個(gè)時(shí),也要用逗號(hào)分隔,它

們與形式參量在順序上相對(duì)應(yīng)。但I(xiàn)BM宏匯編并不要求它們?cè)跀?shù)

量上必須一致。若調(diào)用時(shí)的實(shí)在參量多于形式參量,則多余的部

分被忽略;若實(shí)在參量少于形式參量,則多余的形式參量變?yōu)?/p>

2)PURGE

一個(gè)宏指令名,可以用偽指令PURGE來取消,然后就可以重新定義

格式:

PURGE宏指令名

功能:取消多個(gè)宏定義。

金晨第『章存秋匯編於術(shù)瓶

3)REPT

格式:

REPT〈表達(dá)式〉

;指令體

ENDM

功能:重復(fù)執(zhí)行在它的指令體部分所包含的語句。重復(fù)執(zhí)

行的次數(shù),由表達(dá)式的值所決定。

依第『章富」匯編技術(shù)

例8.4

X=0

REPT10

X=X+1

DBX

ENDM

實(shí)現(xiàn)的功能是把1到10分配給10個(gè)連續(xù)的內(nèi)存單元。

.;..i^ggsfef

-Jc

4)IRP

格式:

IRP形式參量,〈參數(shù)表〉

■:;指令體

ENDM

功能:重復(fù)執(zhí)行指令體部分所包含的語句,重復(fù)的次數(shù)由

參數(shù)表中的參數(shù)的個(gè)數(shù)決定(參數(shù)表中的參數(shù)必須用兩個(gè)尖括號(hào)

括起來,參數(shù)間用逗號(hào)分隔),且每重復(fù)一次,依次用參數(shù)表中

的參數(shù)來代替形式參量。

例8£

IRPX,<1,2,3,4,5,6,7,8,9,10>

DBX

ENDM

因?yàn)閰?shù)表中的參數(shù)個(gè)數(shù)為10,故指令體部分重復(fù)執(zhí)行10

次。例8-4中的指令體部分只有一條偽指令DBX,其中X為形式

參量。在第一次執(zhí)行時(shí)用參數(shù)表中的第一個(gè)參數(shù)1代替形式參量,

就為DB1;第二次執(zhí)行時(shí),用參數(shù)表中的第二個(gè)參數(shù)2代替形式

參量,就為DB2;……所以例8-4也是把1到10分配給10個(gè)連續(xù)

的內(nèi)存單元。

5)IRPC

格式:

IRPC形式參量,字符串(或〈字符串〉)

:;指令體

ENDM

功能:重復(fù)執(zhí)行指令體部分所包含的語句。重復(fù)執(zhí)行的次

數(shù),取決于字符串中的字符個(gè)數(shù),每次重復(fù)時(shí),依次用字符串

的字符代替形式參量。

IRPC偽指令與IRP偽指令很類似,只是用字符串(此字符串

可以包括在兩個(gè)三角括號(hào)中,也可以不包括)代替了IRP指令中的

參數(shù)表。

例8-6

IRPCX,<ABCDEF>

DBX

ENDM

實(shí)現(xiàn)的功能是:把字符A到F分配給內(nèi)存中的6個(gè)連續(xù)單元。

以上MACRO、REPT、IRP和IRPC4個(gè)宏定義的偽指令都

必須以偽指令ENDM作為它的結(jié)束符。

有兩點(diǎn)需要特別指出:

①宏定義也可以像程序設(shè)計(jì)語言中的標(biāo)準(zhǔn)函數(shù)一樣,構(gòu)成

一個(gè)標(biāo)準(zhǔn)函數(shù)庫,供其他源程序使用。以文件的形式組織若干個(gè)

宏定義即形成宏程序庫。程序設(shè)計(jì)中使用了宏程序庫中的宏定義

時(shí),在源程序中應(yīng)使用INCLUDE偽指令。宏匯編程序在匯編源

程序時(shí),當(dāng)遇到該偽指令,就把INCLUDE偽指令所包含的宏程

序庫中的文件掃描一遍,如同在程序中使用自己定義的宏一樣,

在后面的程序中就可以對(duì)宏庫中的宏定義直接進(jìn)行宏調(diào)用了。

②與子程序一樣,宏定義也可以嵌套。宏定義的嵌套有兩

種方式:宏定義嵌套和宏定義內(nèi)嵌套宏調(diào)用。在一個(gè)宏定義中

包含了另一個(gè)宏定義,則稱為宏定義嵌套;在一個(gè)宏定義的宏

體內(nèi)有宏調(diào)用,則稱為宏定義內(nèi)嵌套宏調(diào)用。在宏定義內(nèi)嵌套

宏調(diào)用中,被調(diào)用的宏指令必須是已定義的。宏定義嵌套常用

于產(chǎn)生一些新的宏定義,而宏定義內(nèi)嵌套宏調(diào)用則可以使宏定

義簡化,功能單一,便于通過組合的方法實(shí)現(xiàn)一個(gè)功能較為復(fù)

雜的宏定義。

8.1.3LOCAL偽指令

如果宏定義中含有變量名或標(biāo)號(hào),且在同一源程序中又多

次被宏調(diào)用,那么宏匯編程序在宏展開時(shí),產(chǎn)生多個(gè)相同的變

量名或標(biāo)號(hào),這就不能滿足變量名和標(biāo)號(hào)在同一程序中必須惟

一的要求,從而產(chǎn)生匯編出錯(cuò),即產(chǎn)生uERRORA2005:

SYMBOLISMULTIDEFINED”的錯(cuò)誤。為達(dá)到在宏定義中使用

變量名和標(biāo)號(hào),又能避免這個(gè)錯(cuò)誤的目的,可在宏定義中使用

局部符號(hào)偽指令LOCAL對(duì)變量名或標(biāo)號(hào)進(jìn)行說明。

c第『章富」匯編技術(shù)

格式:

LOCAL〈符號(hào)表〉

功能:對(duì)在符號(hào)表中的每個(gè)符號(hào),在匯編時(shí)每擴(kuò)展一次便

建立一個(gè)“??xxxx”惟一的符號(hào),保證匯編時(shí)生成名字的惟一

性。

說明:

(1)符號(hào)表是在宏定義中定義的變量名和標(biāo)號(hào),多個(gè)符號(hào)之

間用逗號(hào)分隔。

(2)LOCAL偽指令指定的變量名和標(biāo)號(hào)自動(dòng)生成格式為

8.1.4宏和過程的比較

宏和過程都可用來簡化源程序,并可使程序多次對(duì)它們進(jìn)行

調(diào)用,從而使程序結(jié)構(gòu)簡潔清晰,符合結(jié)構(gòu)化程序設(shè)計(jì)風(fēng)格。

因此,對(duì)于那些需重復(fù)使用的程序模塊,既可用過程也可用宏

來實(shí)現(xiàn)。

宏和過程的主要區(qū)別在于:

(1)宏操作可以直接傳遞和接收參數(shù),它不需通過棧等其他

媒介來進(jìn)行,因此編程比較容易。而過程不能直接帶有參數(shù),

當(dāng)過程之間需要傳遞參數(shù)時(shí),必須通過棧、寄存器或存儲(chǔ)器來

進(jìn)行,所以相對(duì)于宏而言,它的編程要復(fù)雜一些。

(2)宏調(diào)用只能簡化源程序的書寫,縮短源程序長度,它并

沒有縮短目標(biāo)代碼的長度,匯編程序處理宏指令時(shí),是把宏體

插入到宏調(diào)用處,所以目標(biāo)程序占用內(nèi)存空間并不因宏操作而

減少。而過程(子程序)調(diào)用卻能縮短目標(biāo)程序的長度,因?yàn)檫^程

在源程序的目標(biāo)代碼中只有一段,無論主程序調(diào)用多少次,除

了增加CALL和RET指令的代碼外,并不增加子程序段代碼。

(3)引入宏操作并不會(huì)在執(zhí)行目標(biāo)代碼時(shí)增加額外的時(shí)間開

銷。相反,過程調(diào)用由于需要保護(hù)和恢復(fù)現(xiàn)場及斷點(diǎn),因而有

額外的時(shí)間開銷,會(huì)延長目標(biāo)程序的執(zhí)行時(shí)間。

若在一個(gè)源程序中多次調(diào)用一段程序,則可用子程序,也

可以用宏指令來簡化源程序。用子程序的方法,匯編后產(chǎn)生的

目標(biāo)代碼少,即目標(biāo)程序占用的內(nèi)存空間少,節(jié)約內(nèi)存空間。

但是,子程序在執(zhí)行時(shí),每調(diào)用一次都要先保護(hù)斷點(diǎn),通常在

程序中還要保護(hù)現(xiàn)場。同樣,在返回時(shí),先要恢復(fù)現(xiàn)場,然后

恢復(fù)斷點(diǎn)(返回)。這些操作都額外增加了時(shí)間,因而執(zhí)行時(shí)間

長,速度慢。而宏指令恰好相反,它的目標(biāo)程序長,占用的內(nèi)

存單元多,但在執(zhí)行時(shí)不需要保護(hù)斷點(diǎn)、現(xiàn)場以及恢復(fù)、返回

等這些額外操作,因而執(zhí)行時(shí)間短,速度快。

c第『章富」匯編技術(shù)衣£■

所以,當(dāng)要代替的程序段較短,速度是主要矛盾時(shí),通常

用宏指令。而當(dāng)要代替的程序段較長,額外操作所附加的時(shí)間

不明顯,節(jié)省存儲(chǔ)空間是主要矛盾時(shí),通常用子程序。宏指令

是機(jī)器的指令系統(tǒng)中沒有的,但又可以作為一條指令使用。所

以,從形式上看,宏指令擴(kuò)充了機(jī)器的指令系統(tǒng)。

8.2重復(fù)匯編和條件匯編

8.2.1重復(fù)匯編

在匯編程序設(shè)計(jì)中,經(jīng)常要連續(xù)地重復(fù)相同的或幾乎完全

相同的代碼序列,這時(shí)可以使用重復(fù)偽指令。

1.重復(fù)偽指令

宏匯編語言提供的重復(fù)偽指令包括REPT、IRP、IRPC,其

格式、功能及使用說明在8.1.2節(jié)中已講述,這里不再贅述。

2.重復(fù)偽指令應(yīng)用舉例

例8?7使用不同重復(fù)偽指令定義10個(gè)數(shù)據(jù),使其內(nèi)容分別

為0,1,…,9o

第一種方法,使用REPT偽指令:

COUNT=0

REPT10

DBCOUNT

COUNT=COUNT+1

ENDM

第二種方法,使用IRP偽指令:

IRPX,<0,1,2,3,4,5,6,7,8,9>

DBX

ENDM

第三種方法,使用IRPC偽指令:

IRPCX0123456789

DBX

ENDM

依第『章富」匯編技術(shù)

以上三種方法具有同樣的功能,匯編后產(chǎn)生的代碼如下

+DB0

+DB1

+DB2

+DB3

+DB4

+DB5

+DB6

+DB7

+DB8

+DB-9

-Jx

依第『章富」匯編技術(shù)

例8-8下面兩條重復(fù)偽指令具有相同的功能。

(1)IRP指令:

IRPREG,<AX,BX,CX,DX>

POPREG

ENDM

-Jx

依第『章富」匯編技術(shù)

(2)IRPC指令:

IRPCRABCD

POPR&X

ENDM

匯編后它們產(chǎn)生的代碼如下:

+POPAX

+POPBX

+POPCX

+POPDX

-Jc

8.2.2條件匯編

條件匯編偽指令可使匯編程序根據(jù)某種條件對(duì)某部分源程

序有選擇地進(jìn)行匯編,在形式上和高級(jí)語言中的條件語句類似,

但實(shí)質(zhì)不同。條件匯編語句是一種說明性語句,其功能由匯編

系統(tǒng)實(shí)現(xiàn);而一般高級(jí)語言的條件語句是執(zhí)行性語句,其功能

由目標(biāo)程序?qū)崿F(xiàn)。

條件匯編語句通常在宏定義中使用,使得宏定義的適用范

圍更廣。一般情況下,使用條件匯編語句可使一個(gè)源文件產(chǎn)生

幾個(gè)不同的源程序,它們可有不同的功能。

依第『章富」匯編技術(shù)

格式:IF條件

語句序列1

[ELSE

語句序列2]

ENDIF

功能:當(dāng)條件為真(滿足)時(shí)執(zhí)行匯編語句序列1,否則執(zhí)行

匯編語句序列2。

-Jx

說明:“條件”為IF偽指令說明符的一部分,ELSE偽指令

及其后面的語句序列2是可選擇部分,表示條件為假(不滿足)時(shí)

的情況。如果屬于非完全分支的判斷,就不用這部分。整個(gè)條

件匯編最后必須用ENDIF偽指令來結(jié)束。語句序列1和語句序列

2中的語句是任意的,也可為條件匯編語句。

以下5組條件匯編開始語句均可選用ELSE語句,以便匯編條

件為假時(shí)執(zhí)行語句序列2,但一個(gè)IF語句只能有一個(gè)ELSE與之對(duì)

應(yīng)。

1)是0否條件語句

語句有:IF和IFE。

①IF語句。

格式:IF表達(dá)式

功能:表達(dá)式值非0,則條件為真,執(zhí)行匯編語句序列1。

②IFE語句。

格式:IFE表達(dá)式

功能:表達(dá)式值為0,則條件為真,執(zhí)行匯編語句序列1。

依第『章富」匯編技術(shù)

2)掃描1否條件語句

語句有:IF1和IF2。

①IF1語句。

格式:IF1

功能:匯編處于第一次掃描時(shí)條件為真。

②IF2語句。

格式:IF2

功能:匯編處于第二次掃描時(shí)條件為真。

.;..i^ggsfef

-Jc

3)符號(hào)有定義否條件語句

語句有:IFDEF和IFNDEF。

①IFDEF語句。

格式:IFDEF符號(hào)

功能:符號(hào)已被定義或已由EXTRN偽指令說明,則條件為真。

②IFNDEF語句。

格式:IFNDEF符號(hào)

功能:符號(hào)未被定義或未由EXTRN偽指令說明,則條件為真。

4)空否條件語句

語句有:IFB和IFNB。

①IFB語句。

格式:IFBv參數(shù)〉

功能:參數(shù)為空格,則條件為真。尖括號(hào)不能省略。

②IFNB語句

格式:IFNBv參數(shù)〉

功能:參數(shù)不為空格,則條件為真。尖括號(hào)不能省略。

5)字符串比較條件語句

語句有:IFIDN和IFDEF。

①IFIDN語句。

格式:IFIDNv字符串1>,v字符串2>

功能:字符串1與字符串2相同,則條件為真。

②IFDIF語句

格式:IFDIFv字符串1>,〈字符串2>

功能:字符串1與字符串2不相同,則條件為真。

說明:這兩條語句只能在宏定義中使用,檢查傳送給兩個(gè)

參數(shù)的實(shí)參是否相同。

例8-9將輸入及輸出字符的DOS功能調(diào)用放在一個(gè)宏定義

中,通過判斷參數(shù)為0還是非0值來選擇是執(zhí)行匯編輸入還是輸

出的DOS功能。

所編制的程序描述如下,其中含有條件匯編的語句。

INOUTMACROX

IFX

MOVAH,2

INT21H;輸出DL中的字符

ELSE

MOVAH,1

INT21H;輸入一個(gè)字符到AL

ENDIF

ENDM

注:二

當(dāng)宏調(diào)用為INOUTO時(shí),表明傳遞給參數(shù)X的值為0,此時(shí)IFX

的條件為假,因此匯編程序只匯編ELSE與ENDIF之間的語句,

這樣,對(duì)該宏調(diào)用來說,實(shí)際上是執(zhí)行下面的兩條指令:

MOVAH,1

INT21H

而當(dāng)宏調(diào)用為INOUT1時(shí),實(shí)際上是執(zhí)行這樣兩條指令:

MOVAH,2

INT21H

8.3匯編語言與高級(jí)語言的混合編程

8.3.1調(diào)用協(xié)議

匯編程序和匯編語言常常以在線匯編語言代碼的形式,通過

過程同高級(jí)語言,如C/C++、BACIC、PASCAL及FORTRAN一

起使用。需要指出的是,這里盡管講的是使用Microsoft匯編語言

過程,但只要提供兼容的調(diào)用協(xié)議,大多數(shù)其他語言也能夠使用。

在與高級(jí)語言接口時(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指示符中指定。

除用這以外還可以用矣全以短歲旨定O

I.c語言調(diào)用協(xié)議

C語言調(diào)用協(xié)議從右到左壓入?yún)?shù),像它們?cè)趨?shù)表里放的

那樣,帶著放在棧上的參數(shù)從匯編語言過程返回,返回結(jié)果或

者放在AX中或者放在DX:AX中。在BP、DI、SLDS、SS和

方向標(biāo)志位被改動(dòng)之前應(yīng)使用匯編語言過程保存起來。這些寄

存器是高級(jí)語言能用到的。圖8-1給出了C語言調(diào)用協(xié)議下近調(diào)

用和遠(yuǎn)調(diào)用的棧。

(SP)

(SP)

圖8-1使用C語言調(diào)用協(xié)議時(shí)的棧內(nèi)容

(a)近程調(diào)用;(b)遠(yuǎn)程調(diào)用

對(duì)棧內(nèi)參數(shù)的訪問由C語言調(diào)用協(xié)議提供,如例8-10所示。

帶*號(hào)的語句是匯編程序加上的,以保持與C語言調(diào)用協(xié)議的一

致。注意搞清楚BP的內(nèi)容如何被壓入棧中,以及BP是如何被

裝入SP值以訪問由C語言程序放在棧中的參數(shù)這兩個(gè)問題。

C第『章富」匯編技術(shù)

例8-10

.LISTALL

.MODELSMALL,C

SSSPROTOC,A:SWORD,A:SWORD

.CODE

SSSPROCC,A:SWORD,B:SWORD

PUSHBP;保存BP

MOVBP,SP;棧地址存入BP

MOVAX,A;使用參數(shù)A

ADDAX,B;使用參數(shù)B

POPBP;恢復(fù)BP

RET00000H

SSSENDP

■■?----??

一Y帶7?提

根據(jù)C語言調(diào)用協(xié)議編寫的匯編語言過程通過指令I(lǐng)NVOKE

而被調(diào)用。INVOKE用來替代標(biāo)準(zhǔn)的CALL指令。INVOKE遵循

C語言調(diào)用協(xié)議,允許匯編語言程序訪問C語言程序和函數(shù)。

INVOKE指令被用來訪問例8-10中的過程,例如,INVOKESSS,

20,30實(shí)現(xiàn)把30加上20后,結(jié)果放入AX中并返回。INVOKE與

CALL的不同之處,按照調(diào)用協(xié)議的要求,INVOKE指令必須將

參數(shù)從棧中全部移出。INVOKE指令的語法要求過程名后必須跟

著全部的參數(shù),參數(shù)間用逗號(hào)隔開。

2.INVOKE指令的使用

用PUSH把參數(shù)壓入堆棧,如果不小心把參數(shù)個(gè)數(shù)搞錯(cuò)了,

就會(huì)使堆棧不平衡,從而使程序從堆棧中取出錯(cuò)誤的返回地址,

引起不可預(yù)料的后果。所以有必要用一條語句來完成自動(dòng)檢驗(yàn)

的任務(wù)。INVOKE語句是能自動(dòng)將所有的參數(shù)壓入棧中,并檢測(cè)

參數(shù)個(gè)數(shù)、類型是否正確,使用CALL來調(diào)用的一個(gè)宏指令。

INVOKE在匯編程序中調(diào)用子程序時(shí),其參數(shù)的傳遞是通過

堆棧來進(jìn)行的。例如,MessageBox。函數(shù)在USER32.INC文件中

是這樣聲明的:

MESSAGEBOX(HWNDHWND,LPCTSTRLPTEXT,

LPCTSTRLPCAPTION,UINTUTYPE),

在匯編程序中可這樣調(diào)用它:

PUSHUTYPE

PUSHLPCAPTION

PUSHLPTEXT

PUSHHWND

CALLMessageBox

PUSH為匯編語言中的進(jìn)棧指令。上面語句的原理是先將函

數(shù)所需要的參數(shù),壓入到堆棧中去,然后再用CALL指令來調(diào)用

該函數(shù)。

需要注意的是,在上述的參數(shù)進(jìn)棧過程中,是從左到右依

次壓入的,即最右面的參數(shù)是最后一個(gè)進(jìn)堆棧,采用的是

PASCAL規(guī)則。引入INVOKE語句后,就可自動(dòng)的將所調(diào)用子程

序中的參數(shù)壓入堆棧中,而無須編程者用手工壓入。所以上面

的代碼就可以變?yōu)?/p>

INVOKEMessageBox,NULL,addrszText,addrszCaption,

MBOKo

addr是用來把變量參數(shù)的地址傳遞給被調(diào)用的函數(shù)(注意,是所

指變量在內(nèi)存中的地址,而不是變量中的值),它只能在

INVOKE語句中使用。

3.PASCAL語言調(diào)用協(xié)議

PASCAL語言調(diào)用協(xié)議用于BASIC、PASCAL和FORTRAN

語言,在WINDOWS中,它也被用于訪問WINDOWS庫文件

(WINH.LIB)中的函數(shù)。PASCAL語言調(diào)用協(xié)議與C語言調(diào)用協(xié)議

的差異在于:參數(shù)是自左至右壓入棧中。如果用在匯編語言過程

中時(shí),PASCAL語言調(diào)用協(xié)議也需要保存寄存器SI、DLDS和SS

的內(nèi)容。方向標(biāo)志位在登錄時(shí)要被清零,并以清除狀態(tài)被返回。

和在C語言調(diào)用協(xié)議中一樣,INVOKE語句也用于由匯編語言進(jìn)

出高級(jí)語言過程。

這一點(diǎn)在匯編語言同WINDOWS一起使用時(shí)格外重要,以

INVOKEMessageBeep,-1為例,如果WINH.LIB庫文件已被程

序裝載,則該指令使揚(yáng)聲器發(fā)出“嘀”的一聲。其他參數(shù)也可

與MessageBeep一起使用,從而由WINDOWS發(fā)出各種失敗提示

音。在C語言程序中,通過在C語言程序的開頭使用指令

#INCLUDE<WINDOWS.H>,就可以訪問WINDOWS應(yīng)用程序

接口(API)。

―二FF-

依第『章富」匯編技術(shù)

存儲(chǔ)器

參數(shù)1

參數(shù)2

CS(返回地址)

IP(返回地址)

BP(BP)

圖8-2使用PASCAL語言調(diào)用協(xié)議時(shí)棧內(nèi)容

-Jx

圖8-2給出了從PASCAL中調(diào)用函數(shù)時(shí)的棧,注意:所有這

些語言調(diào)用的函數(shù)都被認(rèn)為是遠(yuǎn)程調(diào)用,BP給出了存儲(chǔ)參數(shù)的

棧的地址。最右邊的參數(shù)的地址為BP+6,這一點(diǎn)與C語言調(diào)用

協(xié)議正好相反。同C語言調(diào)用協(xié)議一樣,隱蔽的指令將BP壓入

棧,并將SP寫入BP。

第7章富您匯編技術(shù)布更

4.數(shù)據(jù)類型

表8?1各種數(shù)據(jù)類型的比較

MASM數(shù)據(jù)類型C語言數(shù)據(jù)類型PASCAL數(shù)據(jù)類型

BYTEunsignedchar—

SBYTEchar—

WORDunsignedshortSTRING*1

SWORDshortintINTEGER

DWORDunsignedlong—

SDWORDlongLONG(&)

REAL4floatSINGLE(!)

REAL8doubleDOUBLE(#)

REAL10longdouble

8.3.2與C語言的接口

例8-H本例給出了一個(gè)被C語言程序調(diào)用的過程,該過程

使用MODEL語句指示內(nèi)存模型(本例為小模型)和相應(yīng)的調(diào)用協(xié)

議語言(C語言)。PROTO語句把本過程作為外部函數(shù)聲明,并指

定了全部與本過程相關(guān)的參數(shù)的大小和名稱。本過程被作為一

個(gè)近程調(diào)用

.MODELSMALL,C

XIPROTOC,1:SWORD,F:SWORD

.CODE

C第『章富」匯編技術(shù)

XIPROCC,1:SWORD,LSWORD

FILDPI;取出

FADDST,ST(0);計(jì)算2Xpi

MOVAX,1;取1

MOVTEMP,AX

FILDTEMP;取1

FMUL;計(jì)算2XpiXl

MOVAX,F;取F

MOVTEMP,AX

FILDTEMP;取F

FMUL計(jì)算2XpiXlXf

FISTPTEMP保存結(jié)黑

依第『章富」匯編技術(shù)

MOVAX,TEMP;取結(jié)果用以返回C

RET

XIENDP

TEMPDW?;暫存區(qū)

END

-Jx

本過程使用數(shù)值協(xié)處理器計(jì)算電抗值,使用公式Xl=2兀1F。

其中,參數(shù)F和1從C語言程序中傳送到匯編語言過程中,返回值

(XI)作為一個(gè)字長的整型變量由AX傳回C語言程序。通過BP+4

和BP+6給出的地址,可以從棧中取出1和F的數(shù)據(jù)。本例中的

MOVAX,1指令,若轉(zhuǎn)換為代碼應(yīng)為MOVAX,[BP+4],通過

該指令可從棧中取出1值。

例8-12本例給出了主模塊的C語言調(diào)用順序,該程序喉力

打印出電感系數(shù)為4H,頻率為1000Hz的電抗值。注意:本程序

中的計(jì)算結(jié)果被變換為整型。

#include<stdio.h>

externintxl(int1,intf);

voidmainQ

printf(nTheinductivereactanceof4Hat1000Hzis%d\n”,

xl(4,1000));

8.3.3與PASCAL語言的接口

1.有關(guān)的PASCAL語句和調(diào)用約定

PASCAL語言沒有提供CALL調(diào)用語句。PASCAL主程序?qū)?/p>

匯編語言子程序的調(diào)用是通過外部過程和外部函數(shù)調(diào)用的形式

來實(shí)現(xiàn)的。為了保證調(diào)用的正確實(shí)施,PASCAL主程序和被調(diào)

用的匯編語言子程序都要遵從一定的調(diào)用約定。PASCAL語言

中的過程和函數(shù)有所不同。

1)過程方式

在PASCAL程序中,對(duì)要調(diào)用的匯編語言過程必須預(yù)先采用

PROCEDURE說明語句加以定義說明。PROCEDURE語句的格式

為:

PROCEDURE過程名(參數(shù)表):過程屬性;

這樣,PROCEDURE語句將向PASCAL編譯程序提供如下信息:

(1)被調(diào)用的過程名;

(2)此過程是內(nèi)部過程還是外部過程;

(3)過程的參數(shù)名和類型;

(4)是“數(shù)值參數(shù)”還是“引用參數(shù)”。

由于匯編語言子程序是單獨(dú)編寫和匯編的,它相對(duì)PASE

主程序而言總是外部的。所以,其“過程屬性”為EXTERN。

并且,過程名必須在匯編語言程序中用PUBLIC偽指令加以說明。

第(3)項(xiàng)的過程參數(shù)名和類型是符合PASCAL要求的變量標(biāo)識(shí)符

和數(shù)據(jù)類型。在進(jìn)行PASCAL過程調(diào)用時(shí),過程參數(shù)也是通過棧

來進(jìn)行傳遞的。第(4)項(xiàng)的“數(shù)值參數(shù)”和“引用參數(shù)”涉及到

是傳遞參數(shù)變量值,還是傳遞參數(shù)變量地址的問題。當(dāng)一個(gè)變

量是數(shù)值參數(shù)時(shí),主程序把此變量的值入棧,即傳遞給被調(diào)用

過程;否則,主程序把此變量的地址入棧。作為引用參數(shù)的變

量,在PROCEDURE語句中須用VAR或VARS來加以說明。兩者

的區(qū)別在于:對(duì)由VAR說明的參數(shù),主程序須將其變量地址的

偏移量入棧;而對(duì)由VARS說明的參數(shù),除變量地址的偏移量外,

主程序還要將此變量地址的段地址入棧。語句:

PROCEDUREADDP(A,B:INTEGER;VARC:INTEGER):EXTERN;

定義了一個(gè)有3個(gè)參數(shù)的外部過程ADDP。其中,變量A和B是整

型數(shù)值參數(shù),而變量C是整型引用參數(shù);一旦匯編語言過程在

PASCAL主程序中經(jīng)由PROCEDURE語句定義說明后,PASCAL

主程序就可以采用相應(yīng)的過程調(diào)用語句來調(diào)用此匯編語言過程了,

過程調(diào)用語句的格式為

過程名(參數(shù)表)

對(duì)上面的ADDP過程,其相應(yīng)的過程調(diào)用語句為

ADDP(A,B,C)

其中,A,B,C是PASCAL主程序中的整型變量。

在被調(diào)用的匯編語言子程序中,PASCAL對(duì)過程的要求基;

(1)由于寄存器SP不能用于一般的尋址方式,通常用BP來存

取傳遞的調(diào)用參數(shù)。所以,在過程程序開始時(shí)要先把BP的原有

內(nèi)容入棧保存,并在返回PASCAL主程序之前恢復(fù)內(nèi)容。另外,

若要在子程序中改變DS和SS等寄存器的內(nèi)容,也須加以保存和

恢復(fù)。

(2)由于是外部過程,在返回PASCAL主程序時(shí)應(yīng)采用長返

回指令,即進(jìn)行段間返回。

(3)在返回時(shí),應(yīng)取消棧參數(shù),即主程序傳遞給此過程的所

有調(diào)用參數(shù)。

依第『章富」匯編技術(shù)

下面是用匯編語言編寫的ADDP過程程序,在程序中,

PUBLIC指令將過程名ADDP存放。

CODESEGMENT

ASSUMECS:CODE

ADDPPROCFAR

PUBLICADDP

PUSHBP

MOVBP,SP

PUSHAX

《泉第『章富像匯編技術(shù)

PUSHBX

MOVAX,[BP+10]

ADDAX,[BP+8]

MOVBX[BP+6]

MOV[BX],AX

POPBX

POPAX

POPBP

RET6

ADDPENDP

過程的FAR屬性使得后面的RET指令成為長返回指令。RET

指令中的整數(shù)用于消去棧參數(shù),它在返回后將自動(dòng)加入到SP寄

存器中。程序的“RET6”指令執(zhí)行前后棧內(nèi)容的變化如圖8-3所

Zj\O

當(dāng)ADDP過程的C變量為VARS引用參數(shù)時(shí),相應(yīng)的匯編語

言程序有所不同。由于C的段地址,A和B的地址由[BP+10]和

[BP+8]變?yōu)椋跙P+12]和[BP+10]。同時(shí),“RET6”變?yōu)椤癛ET8”。

除此之外,由于C變量不是當(dāng)前DS寄存器所指數(shù)據(jù)段中的變量,

對(duì)它的存取方式也與前不同,如圖8-4所示。

依第『章富」匯編技術(shù)

.

r

YVVVYfQD\______—

—A的內(nèi)容—八八人入入(>JL)xxxxx

Y-B的內(nèi)容—

6

執(zhí)行“RET6”

-C的偏移量一_______________________>

I

-返回段地址CS-

(SP)-?—返1可偏移量IP—

圖8-3棧變化

-Jxr^S

依第『章富」匯編技術(shù)

圖8-4C變量為VARS引用參數(shù)時(shí)的堆棧結(jié)構(gòu)

C第『章富」匯編技術(shù)

CODESEGMENT

ASSUMECS:CODE

ADDPPROCFAR

PUBLICADDP

PUSHBP

MOVBP,SP

PUSHAX

PUSHBX

PUSHES

MOVAX,[BP+12]

《泉第『章富像匯編技術(shù)

ADDAX,[BP+10]

LESBX,[BP+6]

MOVES:[BX],AX

POPES

POPBX

POPAX

POPBP

RET8

ADDPENDP

CODEENDS

2)函數(shù)方式

函數(shù)方式同過程方式很相似。在PASCAL程序中,對(duì)要調(diào)用

的匯編函數(shù)也必須預(yù)先加以說明。不過,此時(shí)采用的是

FUNCTION說明語句,而不是PROCEDURE說明語句。

FUNCTION語句的格式為

FUNCTION函數(shù)名(參數(shù)表):函數(shù)類型;函數(shù)屬性;

在FUNCTION語句中,除增加了一個(gè)“函數(shù)類型”外,其余同

PROCEDURE語句一樣?!昂瘮?shù)類型”符合PASCAL要求的數(shù)據(jù)

類型的語句。如:

FUNCTIONADDF(A,B:INTEGER):

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論