大二上-匯編語(yǔ)言_第1頁(yè)
大二上-匯編語(yǔ)言_第2頁(yè)
大二上-匯編語(yǔ)言_第3頁(yè)
大二上-匯編語(yǔ)言_第4頁(yè)
大二上-匯編語(yǔ)言_第5頁(yè)
已閱讀5頁(yè),還剩45頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

匯編語(yǔ)言與C的混合編程本章結(jié)構(gòu)8.2

TurboC模塊連接方式8.1

TurboC嵌入?yún)R編方式8.3匯編語(yǔ)言在VisualC++中的應(yīng)用基礎(chǔ)知識(shí)本章要點(diǎn)

混合編程是指使用兩種或兩種以上的程序設(shè)計(jì)語(yǔ)言,通過(guò)相互調(diào)用、參數(shù)傳遞、共享數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)信息而形成程序的過(guò)程。采用高級(jí)語(yǔ)言與匯編語(yǔ)言混合編程,從而充分利用各種程序設(shè)計(jì)語(yǔ)言各自的優(yōu)勢(shì),即程序的大部分采用高級(jí)語(yǔ)言編寫(xiě),以提高程序的開(kāi)發(fā)效率;在某些部分利用匯編語(yǔ)言編寫(xiě),以提高程序的運(yùn)行效率。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語(yǔ)句格式8.1.2匯編語(yǔ)句訪問(wèn)C語(yǔ)言的數(shù)據(jù)8.1.3嵌入?yún)R編的編譯過(guò)程

8.1TurboC嵌入編程方式C語(yǔ)言與匯編語(yǔ)言的混合編程的第一種方法是在C語(yǔ)言中嵌入?yún)R編語(yǔ)言,又稱嵌入式編程。其優(yōu)點(diǎn)是內(nèi)嵌的匯編代碼顯得更加簡(jiǎn)潔直觀,程序員不用考慮外部鏈接、命名以及參數(shù)傳遞協(xié)議等問(wèn)題,主要缺點(diǎn)是代碼缺乏可移植性,功能較弱。此種方法一般只用于需要插入?yún)R編語(yǔ)句較少的情況。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語(yǔ)句格式ASM<操作碼><操作數(shù)><;或回車(chē)換行>/*注釋*/在TurboC中,C程序中嵌入?yún)R編語(yǔ)言語(yǔ)句必須以關(guān)鍵字ASM開(kāi)頭,其格式如下:注

意(1)ASM作為關(guān)鍵字不能省略,帶有ASM標(biāo)識(shí)的匯編語(yǔ)言代碼可以看成是C語(yǔ)言的部分程序代碼。當(dāng)C語(yǔ)言編譯器遇到ASM語(yǔ)句時(shí)會(huì)識(shí)別并自動(dòng)調(diào)用匯編語(yǔ)言編譯程序,將它翻譯為機(jī)器碼再嵌入到C語(yǔ)言程序之中。(2)操作碼可以是處理器指令(如PUSH、MOV等),也可以是偽指令(如DB、DW、EXTERN等)。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語(yǔ)句格式ASM<操作碼><操作數(shù)><;或回車(chē)換行>/*注釋*/注

意(3)操作數(shù)是操作碼可以接受的數(shù)據(jù),可以是指令允許的立即數(shù)、寄存器名,也可以是C程序中的常量、變量和標(biāo)號(hào)。(4)C程序中嵌入的匯編代碼后可以有分號(hào)也可以無(wú)分號(hào)。如果匯編代碼后無(wú)分號(hào)則必須以換行符結(jié)束(嵌入的匯編語(yǔ)句是C語(yǔ)言中唯一可以以換行結(jié)束的語(yǔ)句);如果匯編代碼后有分號(hào),則一行中可以有多條嵌入的匯編語(yǔ)句,但一條匯編語(yǔ)句不能跨越兩行。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語(yǔ)句格式ASM<操作碼><操作數(shù)><;或回車(chē)換行>/*注釋*/注

意(6)如果要在C語(yǔ)言程序中嵌入連續(xù)多條匯編語(yǔ)句,可以在每行前面都加上“ASM”關(guān)鍵字,更簡(jiǎn)單的辦法是輸入一個(gè)ASM關(guān)鍵字后,使用括號(hào)"{"和"}"將這些匯編語(yǔ)句括起來(lái)。(5)嵌入的匯編語(yǔ)句的注釋方式必須采用C語(yǔ)言的注釋方式,即必須用“/*”標(biāo)識(shí)注釋的開(kāi)始,用“*/”來(lái)標(biāo)識(shí)注釋的結(jié)束,絕不能像純匯編那樣使用“;”來(lái)作為一條注釋的開(kāi)始。8.1TurboC嵌入編程方式8.1.2匯編語(yǔ)句訪問(wèn)C語(yǔ)言的數(shù)據(jù)

內(nèi)嵌的匯編語(yǔ)句除可以使用指令允許的立即數(shù)、寄存器名外,還可以使用C語(yǔ)言程序中的任何符號(hào)(標(biāo)識(shí)符),包括變量、常量、標(biāo)號(hào)、函數(shù)名、寄存器變量、函數(shù)參數(shù)等;C編譯程序自動(dòng)將它們轉(zhuǎn)換成相應(yīng)匯編語(yǔ)言指令的操作數(shù),并在標(biāo)識(shí)符名前加下劃線。一般來(lái)說(shuō),只要匯編語(yǔ)句能夠使用存儲(chǔ)器操作數(shù)(地址操作數(shù)),就可以采用一個(gè)C語(yǔ)言程序中的符號(hào);同樣,只要匯編語(yǔ)句可以用寄存器作為合法的操作數(shù),就可以使用一個(gè)寄存器變量。8.1TurboC嵌入編程方式8.1.2匯編語(yǔ)句訪問(wèn)C語(yǔ)言的數(shù)據(jù)

對(duì)于具有內(nèi)嵌匯編語(yǔ)句的C程序,C編譯器要調(diào)用匯編程序進(jìn)行匯編。匯編程序在分析一條嵌入式匯編指令的操作數(shù)時(shí),若遇到了一個(gè)標(biāo)識(shí)符,它將在C程序的符號(hào)表中搜索該標(biāo)識(shí)符,但8086寄存器名不在搜索范圍之內(nèi),而且大小寫(xiě)形式的寄存器名都可以使用。在C語(yǔ)言程序中使用嵌入式匯編語(yǔ)句時(shí),還應(yīng)注意以下幾個(gè)問(wèn)題:8.1TurboC嵌入編程方式8.1.2匯編語(yǔ)句訪問(wèn)C語(yǔ)言的數(shù)據(jù)(1)TurboC語(yǔ)言中可以直接使用通用寄存器和段寄存器,只要在寄存器名前加一個(gè)下劃線就可以了。另外,C語(yǔ)言中使用SI和DI指針寄存器作為寄存器變量,利用AX和DX傳遞返回參數(shù)。

如果C語(yǔ)言函數(shù)中沒(méi)有寄存器說(shuō)明,嵌入式匯編語(yǔ)句可以自由地把SI、DI用做暫存寄存器;如果C函數(shù)有寄存器說(shuō)明,嵌入式匯編語(yǔ)句仍可以使用SI、DI,但最好采用C語(yǔ)言寄存器變量名形式。嵌入式匯編語(yǔ)句可以任意使用AX/BX/CX/DX寄存器,以及它們的8位形式。8.1TurboC嵌入編程方式8.1.2匯編語(yǔ)句訪問(wèn)C語(yǔ)言的數(shù)據(jù)(2)內(nèi)嵌匯編指令可以使用轉(zhuǎn)移指令和LOOP循環(huán)指令,但是它們只能在函數(shù)體內(nèi)有效,不允許進(jìn)行段間轉(zhuǎn)移。由于ASM語(yǔ)句中不能給出標(biāo)號(hào),因而轉(zhuǎn)移指令只能使用C語(yǔ)言程序中標(biāo)號(hào)(在C語(yǔ)言程序中通常是定義給GOTO語(yǔ)句使用的)。(3)行內(nèi)匯編語(yǔ)句的操作數(shù)也可以是C語(yǔ)言結(jié)構(gòu)中的某個(gè)成員(字段),引用方法仍然采用下面的形式:結(jié)構(gòu)變量名.結(jié)構(gòu)成員名另一種引用方法是把結(jié)構(gòu)變量的首地址送往某一地址寄存器,然后用該寄存器名(加方括號(hào))再加成員名,中間用圓點(diǎn)隔開(kāi)。8.1TurboC嵌入編程方式8.1.3嵌入?yún)R編的編譯過(guò)程C語(yǔ)言程序中含有嵌入式匯編語(yǔ)言語(yǔ)句時(shí),C編譯器首先將C代碼的源程序(.c)編譯成匯編語(yǔ)言源文件(.asm),然后調(diào)用匯編程序TurboAssembler將產(chǎn)生的匯編語(yǔ)言源文件編譯成目標(biāo)文件(.obj),最后調(diào)用Tlink程序?qū)⒛繕?biāo)文件鏈接成可執(zhí)行文件(.exe)。TurboC2.0在編譯含內(nèi)嵌匯編語(yǔ)句的程序時(shí),只能采用命令行TCC方式,并且如果C源程序沒(méi)有使用#pragmainline預(yù)處理,必須使用-B命令行選項(xiàng)編譯連接。8.1TurboC嵌入編程方式8.1.3嵌入?yún)R編的編譯過(guò)程TurboC2.0在處理匯編語(yǔ)句時(shí)要調(diào)用TASM.EXE。如果沒(méi)有TASM匯編器,可以用Microsoft公司的MASM.EXE來(lái)替代。具體的方法有3種:

(2)把MASM.EXE拷貝或改名為T(mén)ASM.EXE,放到TurboC子目錄中。

(1)用pctools或debug在tcc.exe中查找到TASM,并替換成MASM。(3)在命令行輸入以下內(nèi)容:tcc–b–e/path/masm/exec語(yǔ)言源文件名,其中,-b是使用匯編開(kāi)關(guān),-e是使用另一個(gè)匯編器開(kāi)關(guān),path是MASM或其他的匯編器所在的目錄路徑。8.2

TurboC模塊連接方式

模塊連接方式是匯編語(yǔ)言和C語(yǔ)言連接時(shí)最常用的方法。模塊連接是指分別編制匯編語(yǔ)言程序和C語(yǔ)言程序,C語(yǔ)言程序和匯編語(yǔ)言程序分別編譯后產(chǎn)生各自的目標(biāo)程序.obj文件,然后通過(guò)連接程序LINK將幾個(gè).obj目標(biāo)文件合并,建立一個(gè)單獨(dú)的.exe可執(zhí)行文件。

在這一過(guò)程中,匯編語(yǔ)言程序被看做是C語(yǔ)言可以調(diào)用的函數(shù),匯編語(yǔ)言的程序名就是函數(shù)名。C語(yǔ)言像調(diào)用其他C函數(shù)一樣,通過(guò)匯編語(yǔ)言程序名調(diào)用匯編程序。簡(jiǎn)單來(lái)說(shuō),就是將匯編語(yǔ)言程序作為C語(yǔ)言的外部子過(guò)程調(diào)用。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則8.2.2匯編模塊的編譯和連接8.2.4匯編語(yǔ)言程序?qū)語(yǔ)言程序的調(diào)用8.2.3混合編程的參數(shù)傳遞8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

C編譯器對(duì)C源程序編譯時(shí)要將其中的變量名、過(guò)程名、函數(shù)名等標(biāo)識(shí)符前加下劃線,而匯編程序在匯編時(shí)直接使用,所以被C語(yǔ)言調(diào)用的匯編程序的所有標(biāo)識(shí)符前都要加下劃線,以保持兩者標(biāo)識(shí)符一致。需要指出的是,如果是匯編語(yǔ)言設(shè)置采用C語(yǔ)言類(lèi)型,則不必在標(biāo)識(shí)符前加下劃線。(1)

命名約定此外,C語(yǔ)言對(duì)標(biāo)識(shí)符長(zhǎng)度的要求是不超過(guò)8個(gè)字符,并且區(qū)分大小寫(xiě);而匯編語(yǔ)言則要求標(biāo)識(shí)符長(zhǎng)度不超過(guò)31個(gè)字符,且不區(qū)分大小寫(xiě)。因此,在相互調(diào)用時(shí),匯編源程序中的標(biāo)識(shí)符最好不超過(guò)8個(gè)字符(由于TurboC在PC上支持標(biāo)識(shí)符長(zhǎng)度達(dá)到32個(gè)字符,所以無(wú)此限制),并遵循C語(yǔ)言習(xí)慣采用小寫(xiě)。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

在C語(yǔ)言程序中,C對(duì)所要調(diào)用的外部過(guò)程、函數(shù)、變量均用EXTERN予以說(shuō)明,并且放在主調(diào)用程序之前,一般放在各函數(shù)體外部,說(shuō)明形式如下:(2)

聲明約定extern返回值類(lèi)型函數(shù)名稱(參數(shù)類(lèi)型表);extern變量類(lèi)型變量名;8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

其中,返回值類(lèi)型和變量類(lèi)型是C語(yǔ)言中函數(shù)、變量中所允許的任意類(lèi)型,當(dāng)返回值類(lèi)型空缺時(shí),默認(rèn)為int型。經(jīng)過(guò)說(shuō)明后,這些外部變量、過(guò)程、函數(shù)就可在C程序中直接使用。函數(shù)的參數(shù)在傳遞過(guò)程中要求參數(shù)個(gè)數(shù)、類(lèi)型、順序要一一對(duì)應(yīng)。

為了使匯編語(yǔ)言程序的標(biāo)識(shí)符(子程序名和變量名)能在其他模塊可見(jiàn),讓C語(yǔ)言程序能夠調(diào)用它,必須用public操作符定義它們。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

作為一個(gè)獨(dú)立的匯編語(yǔ)言子程序,當(dāng)然要注意寄存器的保護(hù)和恢復(fù)。(3)

寄存器使用約定

對(duì)于寄存器BP、SP、DS、CS和SS,匯編語(yǔ)言子程序如果要使用它們,并且有可能改變它們的值,TurboC要求進(jìn)行保護(hù)。經(jīng)保護(hù)后,這些寄存器可以使用,但退出前必須加以恢復(fù)。寄存器AX、BX、CX、DX和ES,在匯編語(yǔ)言子程序中通??梢匀我馐褂茫渲械腁X和DX寄存器承擔(dān)了傳遞返回值的任務(wù)。標(biāo)志寄存器也可以任意改變。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

指針寄存器SI和DI比較特殊,因?yàn)門(mén)urboC將它們用做了寄存器變量。如果C程序啟用了寄存器變量,則匯編語(yǔ)言子程序使用寄存器SI和DI前必須保護(hù),退出前恢復(fù)。如果C程序沒(méi)有啟用寄存器變量,則匯編語(yǔ)言子程序不必保護(hù)寄存器SI和DI。TurboC編譯程序提供了一個(gè)編譯選擇項(xiàng)(-r),它可以禁止C編譯程序使用寄存器變量。一般來(lái)說(shuō),建議總是對(duì)SI和DI寄存器進(jìn)行保護(hù)。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

存儲(chǔ)模式處理程序、數(shù)據(jù)、堆棧在主存中的分配和存取,決定代碼和數(shù)據(jù)的默認(rèn)指針類(lèi)型

。存儲(chǔ)模式在C語(yǔ)言中又稱編譯模式或主存模式。TurboC提供了6種存儲(chǔ)模式,分別是:微型模式(Tiny)、小型模式(Small)、緊湊模式(Compact)、中型模式(Medium)、大型模式(Large)和巨型模式(Huge)。作為一個(gè)獨(dú)立的匯編語(yǔ)言子程序,當(dāng)然要注意寄存器的保護(hù)和恢復(fù)。(4)

存儲(chǔ)模式約定為了使匯編語(yǔ)言程序與TurboC語(yǔ)言程序連接到一起,對(duì)于匯編語(yǔ)言簡(jiǎn)化段定義格式來(lái)說(shuō),兩者必須具有相同的存儲(chǔ)模式。匯編語(yǔ)言程序采用.model偽指令,TurboC利用TCC選項(xiàng)-m指定各自的存儲(chǔ)模式。相同的存儲(chǔ)模式將自動(dòng)產(chǎn)生相互兼容的調(diào)用和返回類(lèi)型;同時(shí),匯編程序的段定義偽指令.code、.data等也將產(chǎn)生與TurboC相兼容的段名稱和屬性。8.2

TurboC模塊連接方式8.2.1混合編程的約定規(guī)則

連接前,C語(yǔ)言與匯編語(yǔ)言程序都有各自的代碼段、數(shù)據(jù)段;而連接后,它們的代碼段、數(shù)據(jù)段就合二為一或者彼此相關(guān)。需要特別說(shuō)明的是,被連接的多個(gè)目標(biāo)模塊中,應(yīng)當(dāng)有一個(gè)并且只有一個(gè)具有起始模塊。也就是說(shuō),某個(gè)C語(yǔ)言程序中應(yīng)有main()函數(shù),匯編語(yǔ)言程序不用定義起始執(zhí)行點(diǎn)。而且由于共用一個(gè)堆棧段,混合編程時(shí)通常匯編語(yǔ)言程序無(wú)須設(shè)置堆棧段。8.2

TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞123利用匯編程序編譯匯編語(yǔ)言程序成為.obj目標(biāo)代碼文件。利用C編譯程序編譯C語(yǔ)言程序成為.obj目標(biāo)代碼文件。利用連接程序?qū)⒏鱾€(gè)目標(biāo)代碼文件連接在一起,得到可執(zhí)行程序文件。8.2

TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞C語(yǔ)言程序可以通過(guò)堆棧將參數(shù)傳遞給被調(diào)用函數(shù)。C程序調(diào)用函數(shù)之前,先從該函數(shù)中的最右邊的參數(shù)開(kāi)始依次將參數(shù)壓入堆棧,最后壓入最左邊的參數(shù),參數(shù)壓入堆棧的順序與實(shí)參表中參數(shù)的排列順序相反。當(dāng)被調(diào)用函數(shù)運(yùn)行結(jié)束后,壓入堆棧中的參數(shù)已無(wú)價(jià)值,C程序會(huì)立即調(diào)整堆棧指針SP,使之恢復(fù)壓入?yún)?shù)以前的值,釋放堆棧中為參數(shù)保留的空間。也就是說(shuō),堆棧的平衡是主函數(shù)程序?qū)崿F(xiàn)的,子程序不必在返回時(shí)調(diào)整堆棧指針SP。這就是參數(shù)傳遞的C語(yǔ)言規(guī)則。(1)利用堆棧傳遞參數(shù)8.2

TurboC模塊連接方式8.2.3匯編模塊的編譯和連接(2)返回值得傳遞

被調(diào)用函數(shù)的返回值,按下列規(guī)則傳遞給調(diào)用者:如果返回值小于或等于16位,則將其存放在AX寄存器中;如果返回值是32位,則存放在DX.AX寄存器對(duì)中,其中,DX存儲(chǔ)高16位,AX存儲(chǔ)低16位;如果返回值大于32位,則存放在靜態(tài)變量存儲(chǔ)區(qū),AX寄存器存放指向這個(gè)存儲(chǔ)區(qū)的偏移地址;對(duì)于32位far指針,則還利用DX存放段地址。8.2

TurboC模塊連接方式8.2.3匯編模塊的編譯和連接

由此可見(jiàn),匯編語(yǔ)言子程序向C程序返回處理結(jié)果時(shí),是通過(guò)AX和DX完成的。但對(duì)于不同長(zhǎng)度的返回?cái)?shù)據(jù),使用寄存器的情況也不同。8.2

TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(3)地址參數(shù)的傳遞

C語(yǔ)言程序的參數(shù)傳遞,可采用傳數(shù)值和傳地址兩種方式。如果參數(shù)是傳值的,可直接寫(xiě)出實(shí)際參數(shù);如果參數(shù)是傳址的,則在說(shuō)明中將參數(shù)類(lèi)型說(shuō)明為指針類(lèi)型,調(diào)用時(shí),用“&”取得變量的地址作為實(shí)參傳遞。

在匯編語(yǔ)言子程序中,利用基址指針BP,先取得地址,再間接取內(nèi)容,修改后送回原處,同時(shí)以RET返回。8.2

TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(3)地址參數(shù)的傳遞

以傳址方式傳送參數(shù)時(shí),實(shí)際被壓入堆棧的是參數(shù)所在的邏輯地址。這個(gè)地址也要分為近指針(僅含偏移地址)和遠(yuǎn)指針(含段地址和偏移地址)。C語(yǔ)言程序以tiny、small、compact模式編譯時(shí),它以near近指針傳遞地址,在堆棧占2字節(jié);如果C語(yǔ)言程序以medium、large、huge模式編譯,則地址是32位的遠(yuǎn)指針,在堆棧中要占4字節(jié)。8.2

TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(4)通過(guò)外部變量傳遞參數(shù)

混合編程中,參數(shù)的傳遞也可以通過(guò)共用外部變量實(shí)現(xiàn)。

C語(yǔ)言程序中也可使用匯編語(yǔ)言程序中的變量。此時(shí),要求在匯編語(yǔ)言程序中將該變量用public進(jìn)行說(shuō)明,C程序中也必須用extern說(shuō)明,并且數(shù)據(jù)類(lèi)型對(duì)應(yīng)一致。8.2

TurboC模塊連接方式8.2.4匯編語(yǔ)言程序?qū)語(yǔ)言程序的調(diào)用123

為了使C函數(shù)對(duì)匯編語(yǔ)言程序可見(jiàn),匯編語(yǔ)言程序需要對(duì)所調(diào)用的C語(yǔ)言函數(shù)、變量用關(guān)鍵字EXTERN進(jìn)行說(shuō)明。

參數(shù)的正確傳遞是混合編程的關(guān)鍵。

若匯編語(yǔ)言程序以無(wú)參數(shù)的形式調(diào)用一個(gè)C語(yǔ)言函數(shù),那么,在C語(yǔ)言程序中對(duì)此函數(shù)進(jìn)行定義時(shí),函數(shù)后面應(yīng)該跟一個(gè)空括號(hào)。若匯編語(yǔ)言子程序以傳值方式向C語(yǔ)言函數(shù)傳送數(shù)據(jù),則C語(yǔ)言函數(shù)可用基本類(lèi)型對(duì)參數(shù)進(jìn)行說(shuō)明;若匯編語(yǔ)言子程序以傳址方式向C語(yǔ)言函數(shù)傳送數(shù)據(jù),則C語(yǔ)言函數(shù)應(yīng)該使用指針類(lèi)型對(duì)參數(shù)進(jìn)行說(shuō)明。8.2

TurboC模塊連接方式8.2.4匯編語(yǔ)言程序?qū)語(yǔ)言程序的調(diào)用45

若C語(yǔ)言函數(shù)向匯編語(yǔ)言程序送返回值,則C語(yǔ)言函數(shù)體必須用return語(yǔ)句返回。如果返回值是一個(gè)字,則送給AX;如果為32位,則低16位在AX中,高16位在DX中;更多的數(shù)據(jù)則利用DX:AX返回指針。若沒(méi)有返回值,可以不使用return語(yǔ)句。

一般C語(yǔ)言程序具有起始模塊,即有主函數(shù)。這是由于高級(jí)語(yǔ)言程序假定某些初始化代碼已經(jīng)預(yù)先執(zhí)行過(guò)了,故能確信在高級(jí)語(yǔ)言模塊啟動(dòng)時(shí),適當(dāng)?shù)某跏蓟僮饕呀?jīng)完成。這樣,程序從C語(yǔ)言程序開(kāi)始執(zhí)行;然后調(diào)用匯編語(yǔ)言子程序,進(jìn)而又調(diào)用C語(yǔ)言函數(shù)。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令

在VisualC++中嵌入?yún)R編語(yǔ)句需要用到__asm關(guān)鍵字,這個(gè)關(guān)鍵字有兩種使用方法:(1)匯編指令塊方法:在__asm關(guān)鍵字后用一對(duì)花括號(hào){}將匯編指令括起來(lái)。(2)單條匯編指令方法:在每條匯編指令之前加__asm關(guān)鍵字。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用匯編語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(1)嵌入?yún)R編完全支持的Intel486指令集,允許使用MMX指令。對(duì)于還不能支持的指令,VisualC++中可以使用_EMIT偽指令來(lái)擴(kuò)展。_EMIT偽指令相當(dāng)于MASM中的DB,一次定義一個(gè)字節(jié)內(nèi)容,且只能用于程序代碼段。(2)嵌入?yún)R編可以使用所有的MASM表達(dá)式。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用匯編語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(3)__asm塊中允許使用C/C++的數(shù)據(jù)類(lèi)型和對(duì)象,但不能使用MASM指示符和操作符來(lái)定義數(shù)據(jù)對(duì)象。這里需要特別指出的是,__asm塊中不允許使用MASM中的定義指示符(DB、DW、DD、DQ、DT和DF),也不允許使用DUP和THIS操作符。MASM中的結(jié)構(gòu)和記錄也不再有效,嵌入?yún)R編不接受STRUCT、RECORD、WIDTH或者M(jìn)ASK。(4)盡管嵌入?yún)R編不支持大多數(shù)MASM指示符,但它支持EVEN和ALIGN,當(dāng)需要時(shí),這些指示符在匯編代碼中加入NOP(空操作)指令使標(biāo)號(hào)對(duì)齊到特定邊界。這樣可以使某些處理器取指令時(shí)具有更高的效率。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用匯編語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(5)嵌入?yún)R編不是宏匯編,不能使用MASM宏指示符(MACRO、REPT、IRC、IRP和ENDM)和宏操作符(<>、!、&、%和.TYPE)。(6)必須使用寄存器而不是名稱來(lái)指明段(段名稱“_TEXT”是無(wú)效的),并且段跨越必須顯式地說(shuō)明。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用匯編語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(7)在內(nèi)聯(lián)匯編中,可以用LENGTH、SIZE和TYPE來(lái)獲取C/C++變量和類(lèi)型的大小。(8)嵌入?yún)R編中可以使用C/C++風(fēng)格的注釋,也可以使用匯編語(yǔ)言的注釋,即“;”。(9)一般來(lái)說(shuō),不能假定某個(gè)寄存器在__asm塊開(kāi)始的時(shí)候有已知的值。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用C++語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(1)在嵌入?yún)R編中可以使用C/C++變量以及很多其他的C/C++元素,包括符號(hào)(包括標(biāo)號(hào)、變量和函數(shù)名)、常量(包括符號(hào)常量和枚舉型成員)、宏定義和預(yù)處理指示符、注釋(包括“/**/”和“//”)、類(lèi)型名(包括所有MASM中合法的類(lèi)型)及typedef名稱(通常使用PTR和TYPE操作符,或者使用指定的的結(jié)構(gòu)或枚舉成員)。(2)在嵌入?yún)R編中,可以使用C/C++或匯編語(yǔ)言的基數(shù)計(jì)數(shù)法,如0x100和100H是相等的。(3)嵌入?yún)R編中不能使用如“<<”一類(lèi)的C/C++專用操作符。但C/C++和MASM共有的操作符(如“*”和“[]”操作符),被認(rèn)為是匯編語(yǔ)言的操作符,是可以使用的。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用C++語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(4)在__asm塊中可以引用所有在作用范圍內(nèi)的C/C++符號(hào),包括變量名稱、函數(shù)名稱和標(biāo)號(hào),但是不能訪問(wèn)C++類(lèi)的成員函數(shù)。此外,在嵌入?yún)R編中使用C/C++符號(hào)還有一些其他限制:每條匯編語(yǔ)句只能包含一個(gè)C/C++符號(hào)(多個(gè)符號(hào)只能出現(xiàn)在LENGTH、TYPE或SIZE表達(dá)式中);在__asm塊中引用函數(shù)必須先聲明(否則,編譯器將不能區(qū)別__asm塊中的函數(shù)名和標(biāo)號(hào));在__asm塊中不能使用對(duì)于MASM來(lái)說(shuō)是保留字(不區(qū)分大小寫(xiě))的C/C++符號(hào);在__asm塊中不能識(shí)別結(jié)構(gòu)(Structure)和聯(lián)合(union)標(biāo)簽。(5)嵌入?yún)R編的一個(gè)方便之處是它可以使用名稱來(lái)引用C/C++變量。8.2

TurboC模塊連接方式8.3.1嵌入?yún)R編語(yǔ)句指令123使用括號(hào)把__asm塊包圍住。

把__asm關(guān)鍵字放在每條匯編指令之前。使用經(jīng)典C風(fēng)格的注釋(“/*內(nèi)容*/”),不要使用匯編風(fēng)格的注釋(“;內(nèi)容”)或單行的C/C++注釋(“//內(nèi)容”)。(6)使用C/C++宏可以方便地把匯編代碼插入到源代碼中。但是這其中需要額外地注意,因?yàn)楹陮?huì)擴(kuò)展到一個(gè)邏輯行中。為了不出現(xiàn)問(wèn)題,可以按以下規(guī)則編寫(xiě)宏:8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用C++語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(7)可以在C/C++程序中使用goto語(yǔ)句跳轉(zhuǎn)到__asm塊中的標(biāo)號(hào)處,也可以在__asm塊中轉(zhuǎn)跳到__asm塊里面或外面的標(biāo)號(hào)處。__asm塊內(nèi)的標(biāo)號(hào)是不區(qū)分大小寫(xiě)的(指令、指示符等也是不區(qū)分大小寫(xiě)的)。(8)嵌入?yún)R編不僅可以編寫(xiě)C∕C++函數(shù),還可以調(diào)用C函數(shù)(包括C庫(kù)函數(shù))和非重載的全局C++函數(shù),也可以調(diào)用任何用extern"C"說(shuō)明的函數(shù),但不能調(diào)用C++的成員函數(shù)。因?yàn)樗械臉?biāo)準(zhǔn)頭文件都采用extern"C"說(shuō)明庫(kù)函數(shù),所以C++程序中的嵌入式匯編可以調(diào)用C庫(kù)函數(shù)。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語(yǔ)句指令在__asm塊中使用C++語(yǔ)言應(yīng)注意以下幾點(diǎn):注

意(9)匯編語(yǔ)句通過(guò)參數(shù)名就可以引用參數(shù),采用return語(yǔ)句返回出口參數(shù)。返回值的約定是:對(duì)于小于等于32位的數(shù)據(jù)擴(kuò)展為32位,存放在EAX寄存器中返回;4~8字節(jié)的返回值存放在EDX.EAX寄存器對(duì)中返回;更大字節(jié)數(shù)據(jù)則將它們的地址指針存放在EAX中返回。8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語(yǔ)言模塊VisualC++語(yǔ)言具有3種調(diào)用協(xié)議(callingconvention):_cdecl、_stdcall和_fastcall。VisualC++默認(rèn)的是_cdecl方式,按從右至左的順序壓參數(shù)入棧,由調(diào)用者把參數(shù)彈出棧,而傳送參數(shù)的內(nèi)存棧是由調(diào)用者來(lái)維護(hù)的,返回值在EAX中。(1)采用一致的調(diào)用協(xié)議8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語(yǔ)言模塊

WindowsAPI則采用_stdcall方式,按從右至左的順序壓參數(shù)入棧,由被調(diào)用者把參數(shù)彈出棧,而傳送參數(shù)的內(nèi)存棧是由被調(diào)用者來(lái)維護(hù)的,返回值在EAX中。_stdcall調(diào)用約定在輸出函數(shù)名前加上一個(gè)下劃線前綴,后面加上一個(gè)“@”符號(hào)和其參數(shù)的字節(jié)數(shù)_fastcall調(diào)用的主要特點(diǎn)是速度快,因?yàn)樗峭ㄟ^(guò)寄存器來(lái)傳送參數(shù)的。實(shí)際上,它用ECX和EDX傳送前兩個(gè)雙字(DWORD)或更小的參數(shù),剩下的參數(shù)仍舊自右向左壓棧傳送,被調(diào)用的函數(shù)在返回前清理傳送參數(shù)的內(nèi)存棧,而傳送參數(shù)的內(nèi)存棧是由被調(diào)用者來(lái)維護(hù)的。_fastcall調(diào)用約定在輸出函數(shù)名前加上一個(gè)“@”符號(hào),后面也是一個(gè)“@”符號(hào)和其參數(shù)的字節(jié)數(shù)8.3匯編語(yǔ)言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語(yǔ)言模塊(2)聲明公用函數(shù)名和變量名

對(duì)VisualC++和匯編語(yǔ)言使用的公用函數(shù)和變量應(yīng)該進(jìn)行聲明,并且標(biāo)識(shí)符應(yīng)該一致,C++語(yǔ)言對(duì)標(biāo)識(shí)符區(qū)分字母的大小寫(xiě),而匯編不區(qū)分大小寫(xiě)。

在VisualC++語(yǔ)言程序中,采用extern"C"{}對(duì)所調(diào)用的函數(shù)和變量給予說(shuō)明。說(shuō)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論