版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
匯編語言與C的混合編程本章結(jié)構(gòu)8.2
TurboC模塊連接方式8.1
TurboC嵌入?yún)R編方式8.3匯編語言在VisualC++中的應(yīng)用基礎(chǔ)知識本章要點
混合編程是指使用兩種或兩種以上的程序設(shè)計語言,通過相互調(diào)用、參數(shù)傳遞、共享數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)信息而形成程序的過程。采用高級語言與匯編語言混合編程,從而充分利用各種程序設(shè)計語言各自的優(yōu)勢,即程序的大部分采用高級語言編寫,以提高程序的開發(fā)效率;在某些部分利用匯編語言編寫,以提高程序的運行效率。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語句格式8.1.2匯編語句訪問C語言的數(shù)據(jù)8.1.3嵌入?yún)R編的編譯過程
8.1TurboC嵌入編程方式C語言與匯編語言的混合編程的第一種方法是在C語言中嵌入?yún)R編語言,又稱嵌入式編程。其優(yōu)點是內(nèi)嵌的匯編代碼顯得更加簡潔直觀,程序員不用考慮外部鏈接、命名以及參數(shù)傳遞協(xié)議等問題,主要缺點是代碼缺乏可移植性,功能較弱。此種方法一般只用于需要插入?yún)R編語句較少的情況。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語句格式ASM<操作碼><操作數(shù)><;或回車換行>/*注釋*/在TurboC中,C程序中嵌入?yún)R編語言語句必須以關(guān)鍵字ASM開頭,其格式如下:注
意(1)ASM作為關(guān)鍵字不能省略,帶有ASM標(biāo)識的匯編語言代碼可以看成是C語言的部分程序代碼。當(dāng)C語言編譯器遇到ASM語句時會識別并自動調(diào)用匯編語言編譯程序,將它翻譯為機器碼再嵌入到C語言程序之中。(2)操作碼可以是處理器指令(如PUSH、MOV等),也可以是偽指令(如DB、DW、EXTERN等)。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語句格式ASM<操作碼><操作數(shù)><;或回車換行>/*注釋*/注
意(3)操作數(shù)是操作碼可以接受的數(shù)據(jù),可以是指令允許的立即數(shù)、寄存器名,也可以是C程序中的常量、變量和標(biāo)號。(4)C程序中嵌入的匯編代碼后可以有分號也可以無分號。如果匯編代碼后無分號則必須以換行符結(jié)束(嵌入的匯編語句是C語言中唯一可以以換行結(jié)束的語句);如果匯編代碼后有分號,則一行中可以有多條嵌入的匯編語句,但一條匯編語句不能跨越兩行。8.1TurboC嵌入編程方式8.1.1嵌入?yún)R編語句格式ASM<操作碼><操作數(shù)><;或回車換行>/*注釋*/注
意(6)如果要在C語言程序中嵌入連續(xù)多條匯編語句,可以在每行前面都加上“ASM”關(guān)鍵字,更簡單的辦法是輸入一個ASM關(guān)鍵字后,使用括號"{"和"}"將這些匯編語句括起來。(5)嵌入的匯編語句的注釋方式必須采用C語言的注釋方式,即必須用“/*”標(biāo)識注釋的開始,用“*/”來標(biāo)識注釋的結(jié)束,絕不能像純匯編那樣使用“;”來作為一條注釋的開始。8.1TurboC嵌入編程方式8.1.2匯編語句訪問C語言的數(shù)據(jù)
內(nèi)嵌的匯編語句除可以使用指令允許的立即數(shù)、寄存器名外,還可以使用C語言程序中的任何符號(標(biāo)識符),包括變量、常量、標(biāo)號、函數(shù)名、寄存器變量、函數(shù)參數(shù)等;C編譯程序自動將它們轉(zhuǎn)換成相應(yīng)匯編語言指令的操作數(shù),并在標(biāo)識符名前加下劃線。一般來說,只要匯編語句能夠使用存儲器操作數(shù)(地址操作數(shù)),就可以采用一個C語言程序中的符號;同樣,只要匯編語句可以用寄存器作為合法的操作數(shù),就可以使用一個寄存器變量。8.1TurboC嵌入編程方式8.1.2匯編語句訪問C語言的數(shù)據(jù)
對于具有內(nèi)嵌匯編語句的C程序,C編譯器要調(diào)用匯編程序進行匯編。匯編程序在分析一條嵌入式匯編指令的操作數(shù)時,若遇到了一個標(biāo)識符,它將在C程序的符號表中搜索該標(biāo)識符,但8086寄存器名不在搜索范圍之內(nèi),而且大小寫形式的寄存器名都可以使用。在C語言程序中使用嵌入式匯編語句時,還應(yīng)注意以下幾個問題:8.1TurboC嵌入編程方式8.1.2匯編語句訪問C語言的數(shù)據(jù)(1)TurboC語言中可以直接使用通用寄存器和段寄存器,只要在寄存器名前加一個下劃線就可以了。另外,C語言中使用SI和DI指針寄存器作為寄存器變量,利用AX和DX傳遞返回參數(shù)。
如果C語言函數(shù)中沒有寄存器說明,嵌入式匯編語句可以自由地把SI、DI用做暫存寄存器;如果C函數(shù)有寄存器說明,嵌入式匯編語句仍可以使用SI、DI,但最好采用C語言寄存器變量名形式。嵌入式匯編語句可以任意使用AX/BX/CX/DX寄存器,以及它們的8位形式。8.1TurboC嵌入編程方式8.1.2匯編語句訪問C語言的數(shù)據(jù)(2)內(nèi)嵌匯編指令可以使用轉(zhuǎn)移指令和LOOP循環(huán)指令,但是它們只能在函數(shù)體內(nèi)有效,不允許進行段間轉(zhuǎn)移。由于ASM語句中不能給出標(biāo)號,因而轉(zhuǎn)移指令只能使用C語言程序中標(biāo)號(在C語言程序中通常是定義給GOTO語句使用的)。(3)行內(nèi)匯編語句的操作數(shù)也可以是C語言結(jié)構(gòu)中的某個成員(字段),引用方法仍然采用下面的形式:結(jié)構(gòu)變量名.結(jié)構(gòu)成員名另一種引用方法是把結(jié)構(gòu)變量的首地址送往某一地址寄存器,然后用該寄存器名(加方括號)再加成員名,中間用圓點隔開。8.1TurboC嵌入編程方式8.1.3嵌入?yún)R編的編譯過程C語言程序中含有嵌入式匯編語言語句時,C編譯器首先將C代碼的源程序(.c)編譯成匯編語言源文件(.asm),然后調(diào)用匯編程序TurboAssembler將產(chǎn)生的匯編語言源文件編譯成目標(biāo)文件(.obj),最后調(diào)用Tlink程序?qū)⒛繕?biāo)文件鏈接成可執(zhí)行文件(.exe)。TurboC2.0在編譯含內(nèi)嵌匯編語句的程序時,只能采用命令行TCC方式,并且如果C源程序沒有使用#pragmainline預(yù)處理,必須使用-B命令行選項編譯連接。8.1TurboC嵌入編程方式8.1.3嵌入?yún)R編的編譯過程TurboC2.0在處理匯編語句時要調(diào)用TASM.EXE。如果沒有TASM匯編器,可以用Microsoft公司的MASM.EXE來替代。具體的方法有3種:
(2)把MASM.EXE拷貝或改名為TASM.EXE,放到TurboC子目錄中。
(1)用pctools或debug在tcc.exe中查找到TASM,并替換成MASM。(3)在命令行輸入以下內(nèi)容:tcc–b–e/path/masm/exec語言源文件名,其中,-b是使用匯編開關(guān),-e是使用另一個匯編器開關(guān),path是MASM或其他的匯編器所在的目錄路徑。8.2
TurboC模塊連接方式
模塊連接方式是匯編語言和C語言連接時最常用的方法。模塊連接是指分別編制匯編語言程序和C語言程序,C語言程序和匯編語言程序分別編譯后產(chǎn)生各自的目標(biāo)程序.obj文件,然后通過連接程序LINK將幾個.obj目標(biāo)文件合并,建立一個單獨的.exe可執(zhí)行文件。
在這一過程中,匯編語言程序被看做是C語言可以調(diào)用的函數(shù),匯編語言的程序名就是函數(shù)名。C語言像調(diào)用其他C函數(shù)一樣,通過匯編語言程序名調(diào)用匯編程序。簡單來說,就是將匯編語言程序作為C語言的外部子過程調(diào)用。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則8.2.2匯編模塊的編譯和連接8.2.4匯編語言程序?qū)語言程序的調(diào)用8.2.3混合編程的參數(shù)傳遞8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
C編譯器對C源程序編譯時要將其中的變量名、過程名、函數(shù)名等標(biāo)識符前加下劃線,而匯編程序在匯編時直接使用,所以被C語言調(diào)用的匯編程序的所有標(biāo)識符前都要加下劃線,以保持兩者標(biāo)識符一致。需要指出的是,如果是匯編語言設(shè)置采用C語言類型,則不必在標(biāo)識符前加下劃線。(1)
命名約定此外,C語言對標(biāo)識符長度的要求是不超過8個字符,并且區(qū)分大小寫;而匯編語言則要求標(biāo)識符長度不超過31個字符,且不區(qū)分大小寫。因此,在相互調(diào)用時,匯編源程序中的標(biāo)識符最好不超過8個字符(由于TurboC在PC上支持標(biāo)識符長度達到32個字符,所以無此限制),并遵循C語言習(xí)慣采用小寫。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
在C語言程序中,C對所要調(diào)用的外部過程、函數(shù)、變量均用EXTERN予以說明,并且放在主調(diào)用程序之前,一般放在各函數(shù)體外部,說明形式如下:(2)
聲明約定extern返回值類型函數(shù)名稱(參數(shù)類型表);extern變量類型變量名;8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
其中,返回值類型和變量類型是C語言中函數(shù)、變量中所允許的任意類型,當(dāng)返回值類型空缺時,默認(rèn)為int型。經(jīng)過說明后,這些外部變量、過程、函數(shù)就可在C程序中直接使用。函數(shù)的參數(shù)在傳遞過程中要求參數(shù)個數(shù)、類型、順序要一一對應(yīng)。
為了使匯編語言程序的標(biāo)識符(子程序名和變量名)能在其他模塊可見,讓C語言程序能夠調(diào)用它,必須用public操作符定義它們。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
作為一個獨立的匯編語言子程序,當(dāng)然要注意寄存器的保護和恢復(fù)。(3)
寄存器使用約定
對于寄存器BP、SP、DS、CS和SS,匯編語言子程序如果要使用它們,并且有可能改變它們的值,TurboC要求進行保護。經(jīng)保護后,這些寄存器可以使用,但退出前必須加以恢復(fù)。寄存器AX、BX、CX、DX和ES,在匯編語言子程序中通??梢匀我馐褂?,其中的AX和DX寄存器承擔(dān)了傳遞返回值的任務(wù)。標(biāo)志寄存器也可以任意改變。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
指針寄存器SI和DI比較特殊,因為TurboC將它們用做了寄存器變量。如果C程序啟用了寄存器變量,則匯編語言子程序使用寄存器SI和DI前必須保護,退出前恢復(fù)。如果C程序沒有啟用寄存器變量,則匯編語言子程序不必保護寄存器SI和DI。TurboC編譯程序提供了一個編譯選擇項(-r),它可以禁止C編譯程序使用寄存器變量。一般來說,建議總是對SI和DI寄存器進行保護。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
存儲模式處理程序、數(shù)據(jù)、堆棧在主存中的分配和存取,決定代碼和數(shù)據(jù)的默認(rèn)指針類型
。存儲模式在C語言中又稱編譯模式或主存模式。TurboC提供了6種存儲模式,分別是:微型模式(Tiny)、小型模式(Small)、緊湊模式(Compact)、中型模式(Medium)、大型模式(Large)和巨型模式(Huge)。作為一個獨立的匯編語言子程序,當(dāng)然要注意寄存器的保護和恢復(fù)。(4)
存儲模式約定為了使匯編語言程序與TurboC語言程序連接到一起,對于匯編語言簡化段定義格式來說,兩者必須具有相同的存儲模式。匯編語言程序采用.model偽指令,TurboC利用TCC選項-m指定各自的存儲模式。相同的存儲模式將自動產(chǎn)生相互兼容的調(diào)用和返回類型;同時,匯編程序的段定義偽指令.code、.data等也將產(chǎn)生與TurboC相兼容的段名稱和屬性。8.2
TurboC模塊連接方式8.2.1混合編程的約定規(guī)則
連接前,C語言與匯編語言程序都有各自的代碼段、數(shù)據(jù)段;而連接后,它們的代碼段、數(shù)據(jù)段就合二為一或者彼此相關(guān)。需要特別說明的是,被連接的多個目標(biāo)模塊中,應(yīng)當(dāng)有一個并且只有一個具有起始模塊。也就是說,某個C語言程序中應(yīng)有main()函數(shù),匯編語言程序不用定義起始執(zhí)行點。而且由于共用一個堆棧段,混合編程時通常匯編語言程序無須設(shè)置堆棧段。8.2
TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞123利用匯編程序編譯匯編語言程序成為.obj目標(biāo)代碼文件。利用C編譯程序編譯C語言程序成為.obj目標(biāo)代碼文件。利用連接程序?qū)⒏鱾€目標(biāo)代碼文件連接在一起,得到可執(zhí)行程序文件。8.2
TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞C語言程序可以通過堆棧將參數(shù)傳遞給被調(diào)用函數(shù)。C程序調(diào)用函數(shù)之前,先從該函數(shù)中的最右邊的參數(shù)開始依次將參數(shù)壓入堆棧,最后壓入最左邊的參數(shù),參數(shù)壓入堆棧的順序與實參表中參數(shù)的排列順序相反。當(dāng)被調(diào)用函數(shù)運行結(jié)束后,壓入堆棧中的參數(shù)已無價值,C程序會立即調(diào)整堆棧指針SP,使之恢復(fù)壓入?yún)?shù)以前的值,釋放堆棧中為參數(shù)保留的空間。也就是說,堆棧的平衡是主函數(shù)程序?qū)崿F(xiàn)的,子程序不必在返回時調(diào)整堆棧指針SP。這就是參數(shù)傳遞的C語言規(guī)則。(1)利用堆棧傳遞參數(shù)8.2
TurboC模塊連接方式8.2.3匯編模塊的編譯和連接(2)返回值得傳遞
被調(diào)用函數(shù)的返回值,按下列規(guī)則傳遞給調(diào)用者:如果返回值小于或等于16位,則將其存放在AX寄存器中;如果返回值是32位,則存放在DX.AX寄存器對中,其中,DX存儲高16位,AX存儲低16位;如果返回值大于32位,則存放在靜態(tài)變量存儲區(qū),AX寄存器存放指向這個存儲區(qū)的偏移地址;對于32位far指針,則還利用DX存放段地址。8.2
TurboC模塊連接方式8.2.3匯編模塊的編譯和連接
由此可見,匯編語言子程序向C程序返回處理結(jié)果時,是通過AX和DX完成的。但對于不同長度的返回數(shù)據(jù),使用寄存器的情況也不同。8.2
TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(3)地址參數(shù)的傳遞
C語言程序的參數(shù)傳遞,可采用傳數(shù)值和傳地址兩種方式。如果參數(shù)是傳值的,可直接寫出實際參數(shù);如果參數(shù)是傳址的,則在說明中將參數(shù)類型說明為指針類型,調(diào)用時,用“&”取得變量的地址作為實參傳遞。
在匯編語言子程序中,利用基址指針BP,先取得地址,再間接取內(nèi)容,修改后送回原處,同時以RET返回。8.2
TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(3)地址參數(shù)的傳遞
以傳址方式傳送參數(shù)時,實際被壓入堆棧的是參數(shù)所在的邏輯地址。這個地址也要分為近指針(僅含偏移地址)和遠(yuǎn)指針(含段地址和偏移地址)。C語言程序以tiny、small、compact模式編譯時,它以near近指針傳遞地址,在堆棧占2字節(jié);如果C語言程序以medium、large、huge模式編譯,則地址是32位的遠(yuǎn)指針,在堆棧中要占4字節(jié)。8.2
TurboC模塊連接方式8.2.3混合編程的參數(shù)傳遞(4)通過外部變量傳遞參數(shù)
混合編程中,參數(shù)的傳遞也可以通過共用外部變量實現(xiàn)。
C語言程序中也可使用匯編語言程序中的變量。此時,要求在匯編語言程序中將該變量用public進行說明,C程序中也必須用extern說明,并且數(shù)據(jù)類型對應(yīng)一致。8.2
TurboC模塊連接方式8.2.4匯編語言程序?qū)語言程序的調(diào)用123
為了使C函數(shù)對匯編語言程序可見,匯編語言程序需要對所調(diào)用的C語言函數(shù)、變量用關(guān)鍵字EXTERN進行說明。
參數(shù)的正確傳遞是混合編程的關(guān)鍵。
若匯編語言程序以無參數(shù)的形式調(diào)用一個C語言函數(shù),那么,在C語言程序中對此函數(shù)進行定義時,函數(shù)后面應(yīng)該跟一個空括號。若匯編語言子程序以傳值方式向C語言函數(shù)傳送數(shù)據(jù),則C語言函數(shù)可用基本類型對參數(shù)進行說明;若匯編語言子程序以傳址方式向C語言函數(shù)傳送數(shù)據(jù),則C語言函數(shù)應(yīng)該使用指針類型對參數(shù)進行說明。8.2
TurboC模塊連接方式8.2.4匯編語言程序?qū)語言程序的調(diào)用45
若C語言函數(shù)向匯編語言程序送返回值,則C語言函數(shù)體必須用return語句返回。如果返回值是一個字,則送給AX;如果為32位,則低16位在AX中,高16位在DX中;更多的數(shù)據(jù)則利用DX:AX返回指針。若沒有返回值,可以不使用return語句。
一般C語言程序具有起始模塊,即有主函數(shù)。這是由于高級語言程序假定某些初始化代碼已經(jīng)預(yù)先執(zhí)行過了,故能確信在高級語言模塊啟動時,適當(dāng)?shù)某跏蓟僮饕呀?jīng)完成。這樣,程序從C語言程序開始執(zhí)行;然后調(diào)用匯編語言子程序,進而又調(diào)用C語言函數(shù)。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令
在VisualC++中嵌入?yún)R編語句需要用到__asm關(guān)鍵字,這個關(guān)鍵字有兩種使用方法:(1)匯編指令塊方法:在__asm關(guān)鍵字后用一對花括號{}將匯編指令括起來。(2)單條匯編指令方法:在每條匯編指令之前加__asm關(guān)鍵字。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用匯編語言應(yīng)注意以下幾點:注
意(1)嵌入?yún)R編完全支持的Intel486指令集,允許使用MMX指令。對于還不能支持的指令,VisualC++中可以使用_EMIT偽指令來擴展。_EMIT偽指令相當(dāng)于MASM中的DB,一次定義一個字節(jié)內(nèi)容,且只能用于程序代碼段。(2)嵌入?yún)R編可以使用所有的MASM表達式。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用匯編語言應(yīng)注意以下幾點:注
意(3)__asm塊中允許使用C/C++的數(shù)據(jù)類型和對象,但不能使用MASM指示符和操作符來定義數(shù)據(jù)對象。這里需要特別指出的是,__asm塊中不允許使用MASM中的定義指示符(DB、DW、DD、DQ、DT和DF),也不允許使用DUP和THIS操作符。MASM中的結(jié)構(gòu)和記錄也不再有效,嵌入?yún)R編不接受STRUCT、RECORD、WIDTH或者MASK。(4)盡管嵌入?yún)R編不支持大多數(shù)MASM指示符,但它支持EVEN和ALIGN,當(dāng)需要時,這些指示符在匯編代碼中加入NOP(空操作)指令使標(biāo)號對齊到特定邊界。這樣可以使某些處理器取指令時具有更高的效率。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用匯編語言應(yīng)注意以下幾點:注
意(5)嵌入?yún)R編不是宏匯編,不能使用MASM宏指示符(MACRO、REPT、IRC、IRP和ENDM)和宏操作符(<>、!、&、%和.TYPE)。(6)必須使用寄存器而不是名稱來指明段(段名稱“_TEXT”是無效的),并且段跨越必須顯式地說明。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用匯編語言應(yīng)注意以下幾點:注
意(7)在內(nèi)聯(lián)匯編中,可以用LENGTH、SIZE和TYPE來獲取C/C++變量和類型的大小。(8)嵌入?yún)R編中可以使用C/C++風(fēng)格的注釋,也可以使用匯編語言的注釋,即“;”。(9)一般來說,不能假定某個寄存器在__asm塊開始的時候有已知的值。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用C++語言應(yīng)注意以下幾點:注
意(1)在嵌入?yún)R編中可以使用C/C++變量以及很多其他的C/C++元素,包括符號(包括標(biāo)號、變量和函數(shù)名)、常量(包括符號常量和枚舉型成員)、宏定義和預(yù)處理指示符、注釋(包括“/**/”和“//”)、類型名(包括所有MASM中合法的類型)及typedef名稱(通常使用PTR和TYPE操作符,或者使用指定的的結(jié)構(gòu)或枚舉成員)。(2)在嵌入?yún)R編中,可以使用C/C++或匯編語言的基數(shù)計數(shù)法,如0x100和100H是相等的。(3)嵌入?yún)R編中不能使用如“<<”一類的C/C++專用操作符。但C/C++和MASM共有的操作符(如“*”和“[]”操作符),被認(rèn)為是匯編語言的操作符,是可以使用的。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用C++語言應(yīng)注意以下幾點:注
意(4)在__asm塊中可以引用所有在作用范圍內(nèi)的C/C++符號,包括變量名稱、函數(shù)名稱和標(biāo)號,但是不能訪問C++類的成員函數(shù)。此外,在嵌入?yún)R編中使用C/C++符號還有一些其他限制:每條匯編語句只能包含一個C/C++符號(多個符號只能出現(xiàn)在LENGTH、TYPE或SIZE表達式中);在__asm塊中引用函數(shù)必須先聲明(否則,編譯器將不能區(qū)別__asm塊中的函數(shù)名和標(biāo)號);在__asm塊中不能使用對于MASM來說是保留字(不區(qū)分大小寫)的C/C++符號;在__asm塊中不能識別結(jié)構(gòu)(Structure)和聯(lián)合(union)標(biāo)簽。(5)嵌入?yún)R編的一個方便之處是它可以使用名稱來引用C/C++變量。8.2
TurboC模塊連接方式8.3.1嵌入?yún)R編語句指令123使用括號把__asm塊包圍住。
把__asm關(guān)鍵字放在每條匯編指令之前。使用經(jīng)典C風(fēng)格的注釋(“/*內(nèi)容*/”),不要使用匯編風(fēng)格的注釋(“;內(nèi)容”)或單行的C/C++注釋(“//內(nèi)容”)。(6)使用C/C++宏可以方便地把匯編代碼插入到源代碼中。但是這其中需要額外地注意,因為宏將會擴展到一個邏輯行中。為了不出現(xiàn)問題,可以按以下規(guī)則編寫宏:8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用C++語言應(yīng)注意以下幾點:注
意(7)可以在C/C++程序中使用goto語句跳轉(zhuǎn)到__asm塊中的標(biāo)號處,也可以在__asm塊中轉(zhuǎn)跳到__asm塊里面或外面的標(biāo)號處。__asm塊內(nèi)的標(biāo)號是不區(qū)分大小寫的(指令、指示符等也是不區(qū)分大小寫的)。(8)嵌入?yún)R編不僅可以編寫C∕C++函數(shù),還可以調(diào)用C函數(shù)(包括C庫函數(shù))和非重載的全局C++函數(shù),也可以調(diào)用任何用extern"C"說明的函數(shù),但不能調(diào)用C++的成員函數(shù)。因為所有的標(biāo)準(zhǔn)頭文件都采用extern"C"說明庫函數(shù),所以C++程序中的嵌入式匯編可以調(diào)用C庫函數(shù)。8.3匯編語言在VisualC++中的應(yīng)用8.3.1嵌入?yún)R編語句指令在__asm塊中使用C++語言應(yīng)注意以下幾點:注
意(9)匯編語句通過參數(shù)名就可以引用參數(shù),采用return語句返回出口參數(shù)。返回值的約定是:對于小于等于32位的數(shù)據(jù)擴展為32位,存放在EAX寄存器中返回;4~8字節(jié)的返回值存放在EDX.EAX寄存器對中返回;更大字節(jié)數(shù)據(jù)則將它們的地址指針存放在EAX中返回。8.3匯編語言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語言模塊VisualC++語言具有3種調(diào)用協(xié)議(callingconvention):_cdecl、_stdcall和_fastcall。VisualC++默認(rèn)的是_cdecl方式,按從右至左的順序壓參數(shù)入棧,由調(diào)用者把參數(shù)彈出棧,而傳送參數(shù)的內(nèi)存棧是由調(diào)用者來維護的,返回值在EAX中。(1)采用一致的調(diào)用協(xié)議8.3匯編語言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語言模塊
WindowsAPI則采用_stdcall方式,按從右至左的順序壓參數(shù)入棧,由被調(diào)用者把參數(shù)彈出棧,而傳送參數(shù)的內(nèi)存棧是由被調(diào)用者來維護的,返回值在EAX中。_stdcall調(diào)用約定在輸出函數(shù)名前加上一個下劃線前綴,后面加上一個“@”符號和其參數(shù)的字節(jié)數(shù)_fastcall調(diào)用的主要特點是速度快,因為它是通過寄存器來傳送參數(shù)的。實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的參數(shù),剩下的參數(shù)仍舊自右向左壓棧傳送,被調(diào)用的函數(shù)在返回前清理傳送參數(shù)的內(nèi)存棧,而傳送參數(shù)的內(nèi)存棧是由被調(diào)用者來維護的。_fastcall調(diào)用約定在輸出函數(shù)名前加上一個“@”符號,后面也是一個“@”符號和其參數(shù)的字節(jié)數(shù)8.3匯編語言在VisualC++中的應(yīng)用8.3.2調(diào)用匯編語言模塊(2)聲明公用函數(shù)名和變量名
對VisualC++和匯編語言使用的公用函數(shù)和變量應(yīng)該進行聲明,并且標(biāo)識符應(yīng)該一致,C++語言對標(biāo)識符區(qū)分字母的大小寫,而匯編不區(qū)分大小寫。
在VisualC++語言程序中,采用extern"C"{}對所調(diào)用的函數(shù)和變量給予說明。說
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)新教師的培訓(xùn)工作計劃范文
- 2025初三新學(xué)期個人學(xué)習(xí)計劃書2
- 幼兒園中秋節(jié)活動計劃
- 公司業(yè)務(wù)員個人工作回顧及發(fā)展計劃
- 2025稅務(wù)部門年終工作計劃
- 門五金商業(yè)計劃書
- “工會計劃學(xué)?!惫ぷ饔媱?/a>
- 2025語文一年級下冊學(xué)期教學(xué)計劃
- 《地震地質(zhì)基礎(chǔ)》課件
- 《地鐵暗挖施工工法》課件
- 人際溝通.從心開始(大學(xué)生人際交往)
- KYN28-12A開關(guān)柜技術(shù)規(guī)范書
- 化療藥物滲漏PDCA循環(huán)分析
- 國開《小學(xué)數(shù)學(xué)教學(xué)研究》形考任務(wù)二
- 維修方案模板
- 冶金行業(yè)特殊工種有哪些崗位
- 初中部綜合素質(zhì)評價實施方案范本(三篇)
- 2023湖南省永州市七年級上學(xué)期語文期末試卷及答案
- 仲夏夜之夢-中英對照
- 廣州市本級政府投資項目估算編制指引
- 課堂觀察量表
評論
0/150
提交評論