程序語言混編_第1頁
程序語言混編_第2頁
程序語言混編_第3頁
程序語言混編_第4頁
程序語言混編_第5頁
已閱讀5頁,還剩30頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

匯編語言沒有高級(jí)語言要占用較大的存儲(chǔ)空間和較長的運(yùn)行時(shí)間等缺點(diǎn),它的運(yùn)行速度快是高級(jí)語言所不能比擬的??梢哉f高級(jí)語言與匯編語言各有千秋。有時(shí)我們采用高級(jí)語言編程速度達(dá)不到要求,全部采用匯編語言編程工作量又大,此時(shí)可以采用"混合"編程,彼此相互調(diào)用,進(jìn)行參數(shù)傳遞,共享數(shù)據(jù)結(jié)構(gòu)及數(shù)據(jù)信息,是一種有效的編程方法。這種方法可以發(fā)揮各種語言的優(yōu)勢(shì)和特點(diǎn),充分利用現(xiàn)有的多種實(shí)用程序、庫程序等使軟件的開發(fā)周期大大縮短。1高級(jí)語言與匯編語言的接口需要解決的問題1、 需要說明和建立調(diào)用者與被調(diào)用者間的關(guān)系被調(diào)用的過程或函數(shù)應(yīng)預(yù)先說明為外部類型,如匯編子程序,應(yīng)用PUBLIC說明其可被外部模塊引用;調(diào)用程序則應(yīng)預(yù)先說明要引用的外部模塊名。2、 參數(shù)傳遞問題在匯編子程序之間通常采用寄存器作為參數(shù)傳遞的工具,匯編語言與高級(jí)語言程序間的參數(shù)傳遞,一般采用堆棧來傳遞,即調(diào)用程序?qū)?shù)依次壓入堆棧中,當(dāng)被轉(zhuǎn)調(diào)用程序后,再從堆棧中依次彈出參數(shù)作為操作數(shù)使用。為此,必須了解各種語言的堆棧結(jié)構(gòu)、生成方式和入棧方式等。BASIC、FORTRAN、PASCAL等語言其參數(shù)進(jìn)棧順序是與參數(shù)在參數(shù)表中出現(xiàn)的順序相同,即從右到左;而C語言則相反。2C語言與匯編語言的接口2.1C語言調(diào)用匯編子程序?在C程序中使用關(guān)鍵字"ExTERn"對(duì)函數(shù)作顯式說明。?參數(shù)傳遞順序是按其在參數(shù)表中出現(xiàn)的順序的反序被壓入堆棧中,即第一個(gè)參數(shù)最后進(jìn)入堆棧,它在棧中的地址最低。?對(duì)不同的存儲(chǔ)模式(極小、小、緊湊、中、大和巨)要選用不同的匯編語言格式,如C程序?yàn)樾∧J?,匯編用近過程,C程序?yàn)榇竽J?,匯編用遠(yuǎn)過程。?匯編程序取C的參數(shù)。遠(yuǎn)過程返回地址占四個(gè)字節(jié),BP壓入占二字節(jié),所以第一個(gè)參數(shù)在BP+6所指向的單元。對(duì)于近過程第一個(gè)參數(shù)在BP+4所指向的單元。?匯編程序中寄存器的保護(hù)。TuRboC允許子過程使用SI和DI存放局部變量,當(dāng)寄存器變量多于二個(gè)時(shí),多余部分會(huì)自動(dòng)轉(zhuǎn)到堆棧中存儲(chǔ)。因此,匯編過程的格式為:PUSHBPMOVBP,SPPUSHDIPUSHSI3POPSIPOPDIPOPBPRET?返回值。每種C數(shù)據(jù)類型都有一個(gè)標(biāo)準(zhǔn)的返回位置,一般在AX中(極小、小、中模式),DX:AX(緊湊、大、巨模式),如:chaR,unSignEdchaR,Enum,ShoRTinT等,返回值位置為AX,且返回?cái)?shù)據(jù)必須放置在RET指令之前。匯編子程序要定義為遠(yuǎn)過程,并用PUBLIC偽指令把過程名定義為公共。例:#includE"STdio.h〃#includE〃STdlib.h〃chaRMESSagE[]=〃MESSagE";inTfaRREVSTR(chaRfaRSTR);Voidmain(Void)(REVSTR((chaRfaR)MESSagE);printf(〃%S〃,MESSagE);}REVSTR.asmPUBLIC-REVSTR-REVSTRPROCPUSHBPMOVBP,SPPUSHDSPUSHSIPUSHDI■■■POPSIPOPAXMOVDS,AXPOPBPMOVAX,CXRETREVSTRENDPEND2.2C語言嵌入?yún)R編在C程序中允許直接編寫匯編語言代碼,這稱作嵌入?yún)R編。C程序中嵌入?yún)R編后可以無分號(hào)(C語言的語句以分號(hào)結(jié)束,匯編語句是C語言中唯一以換行結(jié)束的語句),以關(guān)鍵詞ASM張一個(gè)嵌入?yún)R編指令,如需多個(gè)ASM語句,可以將它們放在花括號(hào)內(nèi)。如,ASMMOVAX,DX/注釋/ASMPUSHAX}/注釋/C語言允許嵌入四類匯編命令:一般指令、串指令、跳轉(zhuǎn)指令、數(shù)據(jù)分配和定義指令,嵌入?yún)R編比調(diào)用匯編子程序更方便、靈活、功能也更強(qiáng)。但嵌入?yún)R編不是一個(gè)完整的匯編程序,所以許多錯(cuò)誤不能馬上檢查出來。3結(jié)束語采用兩種或兩種以上的編程語言組合編程,彼此相互調(diào)用,進(jìn)行參數(shù)傳遞,是一種有效的程序設(shè)計(jì)方法。這種方法可以充分發(fā)揮各種語言的優(yōu)勢(shì),充分利用現(xiàn)有的實(shí)用程序,是當(dāng)前程序接口技術(shù)的一個(gè)重要研究和應(yīng)用領(lǐng)域WIN-TC使用TC2內(nèi)核所以嵌入?yún)R編得用TC2的語法:方法是使用asm關(guān)鍵字:其格式是:asmopcode<operands><;newline>例如:main()(char*c="hello,world\n\r$";asmmovah,9asmmovdx,casmint33printf("Yousucessed!");}/***************C內(nèi)嵌匯編示例***************/#include"stdio.h"#include"conio.h"intmin(intv1,intv2)(asmmovax,v1;asmcmpax,v2;asmjleminexit;asmmovax,v2;minexit:return(_AX);}main()(printf("min(10,3)is%d\nmin(34,552)is%d”,min(10,3),min(34,552));getch();}現(xiàn)以Microsoft的quickc和MASM來加以說明:一、 直接插入法:一般只用于需插入的匯編語句比較簡短的情況。如顯示一行字符的程序:charconst*message="theplanetearth.\n$";main()(_asm(movah,9movdx,message/*注意offset偽操作C編譯器不能識(shí)別*/int21h}}二、 C語言程序調(diào)用匯編語言過程法:C語言程序經(jīng)編譯后產(chǎn)生.OBJ文件,匯編程序經(jīng)匯編后也產(chǎn)生.OBJ文件,然后由連接程序把他們連接起來而形成.EXE可執(zhí)行文件。應(yīng)注意以下幾個(gè)問題:控制傳送問題:既然匯編語言程序是C語言程序的子過程,在匯編語言程序中應(yīng)把過程名作為外部符號(hào)來處理,所以應(yīng)在程序中聲明PUBLIC過程名。C語言程序中把此過程名定義為外部符號(hào)(extern)o且匯編語言中的過程名前應(yīng)加下劃線。參數(shù)傳送問題:高級(jí)語言通過堆棧把參數(shù)傳送給匯編語言程序。C語言規(guī)定參數(shù)入棧的次序一程序中見到它們的次序相反,或者說C語言按從右到左的次序使參數(shù)入棧。如函數(shù):sub(x,y,z)先使z入棧,然后是y,最后是x.調(diào)用匯編語言過程時(shí),同樣要把返回點(diǎn)保存入棧。如果過程為FAR屬性,則CS和IP將先后入棧;如果過程為NEAR,則只保存IP。如:.MODELMEDIUM.CODEPUBLIC_SUB_SUBPROCFARPUSHBPMOVBP,SPMOVAX,[BP+6];[BP+2]為IP,[BP+4]為CS(遠(yuǎn)調(diào)用)MOVBX,[BP+8];[BP+6]為第一個(gè)參數(shù),[BP+8]為第二個(gè)參數(shù)...popBPRET_SUBENDPEND以上說明的是C語言程序給匯編語言子過程傳達(dá)室送參數(shù)的方法,如果匯編語言子過程有參數(shù)要回送給C語言程序,則應(yīng)通過累加器回送。3.還應(yīng)該說明的是,匯編程序子過程中可以任意使用AX、BX、CX、DX、ES,如需要使用BP、SP、DI、SI、CS、DS、SS寄存器時(shí),則應(yīng)先把它們的原始內(nèi)容保存入棧,并在子程序結(jié)束前恢復(fù)它們的原始內(nèi)容。下面舉例說明:使用C語言調(diào)用匯編語言子過程dif.asm計(jì)算二數(shù)之差并在C語言中顯示其結(jié)果。C語言程序:externunsignedlongdif(int,int);main()(printf("Thedifferenceisequalto%u,dif(8400,125));}匯編程序子過程dif.asm.modelsmall.codepublic_dif_difprocnearpushbpmovbp,spsubdx,dxmovax,[bp+4];因?yàn)镹EAR過程,調(diào)用時(shí)只壓入了IP。subax,[bp+6]sbbdx,0popbpret_difendpendc語言和匯編的問題。懸賞分:100-解決時(shí)間:2007-6-516:42#include<stdio.h>voidprint()(_asm(DSEGSEGMENTMESSAGEDB'HOWDOYUODO',0DH,0AH,024HDSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGBEGIN:MOVAX,DSEGMOVDS,AXLEADX,OFFSETMESSAGEMOVAH,9INT21HMOVAH,4CHINT21HCSEGENDSENDBEGIN}}voidmain()(print();}怎么不可以運(yùn)行用的是VC6.0

問題補(bǔ)充:不要復(fù)制一大堆提問者:xiaozi086520提問者:xiaozi086520-初入江湖一.級(jí)最佳答案上面的仁兄mian()不是在嗎,你沒看到?VC是可以嵌入?yún)R編,可是你嵌入的是一個(gè)完整的匯編程序,這有些不合理吧.試想,如果可以嵌入完整的匯編程序,那VC豈不是可以叫VA(VisualAsm)了:)你把那些定義段的偽代碼去掉,然后將變量定義放在__asm(}前面(嵌入代碼可以訪問到這些變量的).然后再編譯,應(yīng)該沒問題了:)在VC中嵌入?yún)R編,只需在_asm(加入實(shí)現(xiàn)應(yīng)用的匯編代碼。}就行了?;卮鹫撸簒iao086-江湖新秀五級(jí)5-3121:18其他回答共4條你的main函數(shù)在什么地方,編譯器只能從你的主函數(shù)開始處理,我都沒看見你的main函數(shù),你說編譯器怎么能執(zhí)行?回答者:no2iverson-助理一級(jí)5-3121:14hehe是不是啊,我要看一下才能回答你的問題回答者:飄_月亮在北-初.入江湖一級(jí)5-3122:35DSEGSEGMENTMESSAGEDB'HOWDOYUODO',0DH,0AH,024HDSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEG這些都是鳥語,vc識(shí)別不了。vc是支持嵌入?yún)R編,不是支持匯編可以這樣寫intaaa;_asm(moveax,aaa}如何在C語言中嵌入?yún)R編?°懸賞分:5-提問時(shí)間2007-5-2513:30RT,如下:#include<stdio>voidmain()(__asm(movah,01hint21h}printf("hello\n");}上邊那個(gè)例子用VC6.0編譯的時(shí)候不能通過,說那個(gè)int21h中斷有問題但是在TC環(huán)境下卻說"__asm"是undefinedsymbol我應(yīng)該怎么寫代碼才能通過編譯啊?謝謝上面的只是一個(gè)簡單的例子,真正的作業(yè)是要嵌入一段顯示圖形的代碼,只要幫我把上邊那個(gè)編譯過去就行了,剩下的我自己搞定提問者:yz12121-試用期一級(jí)其他回答共2條在VisualC++中使用內(nèi)聯(lián)匯編--使用內(nèi)聯(lián)匯編可以在C/C++代碼中嵌入?yún)R編語言指令,而且不需要額外的匯編和連接步驟。在VisualC++中,內(nèi)聯(lián)匯編是內(nèi)置的編譯器,因此不需要配置諸如MASM一類的獨(dú)立匯編工具。這里,我們就以VisualStudio.NET2003為背景,介紹在VisualC++中使用內(nèi)聯(lián)匯的相關(guān)知識(shí)(如果是早期的版本,可能會(huì)有些許出入)。內(nèi)聯(lián)匯編代碼可以使用C/C++變量和函數(shù),因此它能非常容易地整合到C/C++代碼中。它能做一些對(duì)于單獨(dú)使用C/C++來說非常笨重或不可能完成的任務(wù)。一、優(yōu)點(diǎn)使用內(nèi)聯(lián)匯編可以在C/C++代碼中嵌入?yún)R編語言指令,而且不需要額外的匯編和連接步驟。在VisualC++中,內(nèi)聯(lián)匯編是內(nèi)置的編譯器,因此不需要配置諸如MASM一類的獨(dú)立匯編工具。這里,我們就以VisualStudio.NET2003為背景,介紹在VisualC++中使用內(nèi)聯(lián)匯的相關(guān)知識(shí)(如果是早期的版本,可能會(huì)有些許出入)。內(nèi)聯(lián)匯編代碼可以使用C/C++變量和函數(shù),因此它能非常容易地整合到C/C++代碼中。它能做一些對(duì)于單獨(dú)使用C/C++來說非常笨重或不可能完成的任務(wù)。內(nèi)聯(lián)匯編的用途包括:使用匯編語言編寫特定的函數(shù);編寫對(duì)速度要求非常較高的代碼;在設(shè)備驅(qū)動(dòng)程序中直接訪問硬件;編寫naked函數(shù)的初始化和結(jié)束代碼。二、關(guān)鍵字使用內(nèi)聯(lián)匯編要用到__asm關(guān)鍵字,它可以出現(xiàn)在任何允許C/C++語句出現(xiàn)的地方。我們來看一些例子:簡單的__asm塊:__asm(MOVAL,2MOVDX,0xD007OUTAL,DX}在每條匯編指令之前加__asm關(guān)鍵字:__asmMOVAL,2__asmMOVDX,0xD007__asmOUTAL,DX因?yàn)開_asm關(guān)鍵字是語句分隔符,所以可以把多條匯編指令放在同一行:__asmMOVAL,2__asmMOVDX,0xD007__asmOUTAL,DX顯然,第一種方法與C/C++的風(fēng)格很一致,并且把匯編代碼和C/C++代碼清楚地分開,還避免了重復(fù)輸入__asm關(guān)鍵字,因此推薦使用第一種方法。不像在C/C++中的"{}",__asm塊的"{}"不會(huì)影響C/C++變量的作用范圍。同時(shí),__asm塊可以嵌套,而且嵌套也不會(huì)影響變量的作用范圍。為了與低版本的VisualC++兼容,_asm和__asm具有相同的意義。另外,VisualC++支持標(biāo)準(zhǔn)C++的asm關(guān)鍵字,但是它不會(huì)生成任何指令,它的作用僅限于使編譯器不會(huì)出現(xiàn)編譯錯(cuò)誤。要使用內(nèi)聯(lián)匯編,必須使用__asm而不是asm關(guān)鍵字。三、匯編語言指令集內(nèi)聯(lián)匯編支持IntelPentium4和AMDAthlon的所有指令。更多其它處理器的指令可以通過_EMIT偽指令來創(chuàng)建(_EMIT偽指令說明見下文)。MASM表達(dá)式在內(nèi)聯(lián)匯編代碼中,可以使用所有的MASM表達(dá)式(MASM表達(dá)式是指用來計(jì)算一個(gè)數(shù)值或一個(gè)地址的操作符和操作數(shù)的組合)。數(shù)據(jù)指示符和操作符雖然__asm塊中允許使用C/C++的數(shù)據(jù)類型和對(duì)象,但它不能使用MASM指示符和操作符來定義數(shù)據(jù)對(duì)象。這里特別指出,__asm塊中不允許MASM中的定義指示符(DB、DW、DD、DQ、DT和DF),也不允許使用DUP和THIS操作符。MASM中的結(jié)構(gòu)和記錄也不再有效,內(nèi)聯(lián)匯編不接受STRUC、RECORD、WIDTH或者M(jìn)ASK。EVEN和ALIGN指示符盡管內(nèi)聯(lián)匯編不支持大多數(shù)MASM指示符,但它支持EVEN和ALIGN。當(dāng)需要的時(shí)候,這些指示符在匯編代碼里面加入NOP指令(空操作)使標(biāo)號(hào)對(duì)齊到特定邊界。這樣可以使某些處理器取指令時(shí)具有更高的效率。MASM宏指示符內(nèi)聯(lián)匯編不是宏匯編,不能使用MASM宏指示符(MACRO、REPT、IRC、IRP和ENDM)和宏操作符(<>、!、&、%和.TYPE)。段必須使用寄存器而不是名稱來指明段(段名稱"_TEXT"是無效的)。并且,段跨越必須顯式地說明,如ES:[EBX]。類型和變量大小在內(nèi)聯(lián)匯編中,可以用LENGTH、SIZE和TYPE來獲取C/C++變量和類型的大大小。LENGTH操作符用來取得C/C++中數(shù)組的元素個(gè)數(shù)(如果不是一個(gè)數(shù)組,則結(jié)果為1)。SIZE操作符可以獲取C/C++變量的大小(一個(gè)變量的大小是LENGTH和TYPE的乘積)。TYPE操作符可以返回C/C++類型和變量的大?。ㄈ绻兞渴且粋€(gè)數(shù)組,它得到的是數(shù)組中單個(gè)元素的大小)。例如,程序中定義了一個(gè)8維的整數(shù)型變量:intiArray[8];下面是C和匯編表達(dá)式中得到的iArray及其元素的相關(guān)值:__asmCSizeLENGTHiArraysizeof(iArray)/sizeof(iArray[0])8SIZEiArraysizeof(iArray)32TYPEiArraysizeof(iArray[0])4注釋內(nèi)聯(lián)匯編中可以使用匯編語言的注釋,即";"。例如:__asmMOVEAX,OFFSETpbBuff;LoadaddressofpbBuff因?yàn)镃/C++宏將會(huì)展開到一個(gè)邏輯行中,為了避免在宏中使用匯編語言注釋帶來的混亂,內(nèi)聯(lián)匯編也允許使用C/C++風(fēng)格的注釋。_EMIT偽指令_EMIT偽指令相當(dāng)于MASM中的DB,但是_EMIT一次只能在當(dāng)前代碼段(.text段)中定義一個(gè)字節(jié)。例如:__asm(JMP_CodeLabel_EMIT0x00;定義混合在代碼段的數(shù)據(jù)_EMIT0x01_CodeLabel:;這里是代碼_EMIT0x90;NOP指令}寄存器使用一般來說,不能假定某個(gè)寄存器在__asm塊開始的時(shí)候有巳知的值。寄存器的值將不能保證會(huì)從__asm塊保留到另外一個(gè)__asm塊中。如果一個(gè)函數(shù)聲明為__fastcall調(diào)用方式,則其參數(shù)將通過寄存器而不是堆棧來傳遞。這將會(huì)使__asm塊產(chǎn)生問題,因?yàn)楹瘮?shù)無法被告知哪個(gè)參數(shù)在哪個(gè)寄存器中。如果函數(shù)接收了EAX中的參數(shù)并立即儲(chǔ)存一個(gè)值到EAX中的話,原來的參數(shù)將丟失掉。另外,在所有聲明為__fastcall的函數(shù)中,ECX寄存器是必須一直保留的。為了避免以上的沖突,包含__asm塊的函數(shù)不要聲明為__fastcall調(diào)用方式。提示:如果使用EAX、EBX、ECX、EDX、ESI和EDI寄存器,你不需要保存它。但如果你用到了DS、SS、SP、BP和標(biāo)志寄存器,那就應(yīng)該用PUSH保存這些寄存器。提示:如果程序中改變了用于STD和CLD的方向標(biāo)志,必須將其恢復(fù)到原來的值。四、使用C/C++元素可用的C/C++元素C/C++與匯編語言可以混合使用,在內(nèi)聯(lián)匯編中可以使用C/C++變量以及很多其它的C/C++元素,包括:符號(hào),包括標(biāo)號(hào)、變量和函數(shù)名;常量,包括符號(hào)常量和枚舉型成員;宏定義和預(yù)處理指示符;注釋,包括"/**/"和"http://";類型名,包括所有MASM中合法的類型;typedef名稱,通常使用PTR和TYPE操作符,或者使用指定的的結(jié)構(gòu)或枚舉成員。在內(nèi)聯(lián)匯編中,可以使用C/C++或匯編語言的基數(shù)計(jì)數(shù)法。例如,0x100和100H是相等的。操作符使用內(nèi)聯(lián)匯編中不能使用諸如"<<"一類的C/C++操作符。但是,C/C++和MASM共有的操作符(比如"*"和"[]"操作符),都被認(rèn)為是匯編語言的操作符,是可以使用的。舉個(gè)例子:intiArray[10];__asmMOViArray[6],BX;StoreBXatiArray+6(Notscaled)iArray[6]=0;//Store0atiArray+12(Scaled)提示:在內(nèi)聯(lián)匯編中,可以使用TYPE操作符使其與C/C++一致。比如,下面兩條語句是一樣的:__asmMOViArray[6*TYPEint],0;Store0atiArray+12iArray[6]=0;//Store0atiArray+12C/C++符號(hào)使用在__asm塊中可以引用所有在作用范圍內(nèi)的C/C++符號(hào),包括變量名稱、函數(shù)名稱和標(biāo)號(hào)。但是不能訪問C++類的成員函數(shù)。下面是在內(nèi)聯(lián)匯編中使用C/C++符號(hào)的一些限制:每條匯編語句只能包含一個(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來說是保留字的C/C++符號(hào)(不區(qū)分大小寫)。MASM保留字包含指令名稱(如PUSH)和寄存器名稱(如ESI)等。在__asm塊中不能識(shí)別結(jié)構(gòu)和聯(lián)合標(biāo)簽。訪問C/C++中的數(shù)據(jù)內(nèi)聯(lián)匯編的一個(gè)非常大的方便之處是它可以使用名稱來引用C/C++變量。例如,如果C/C++變量iVar在作用范圍內(nèi):__asmMOVEAX,iVar;StoresthevalueofiVarinEAX如果C/C++中的類、結(jié)構(gòu)或者枚舉成員具有唯一的名稱,則在__asm塊中可以只通過成員名稱來訪問(省略"."操作符之前的變量名或typedef名稱)。然而,如果成員不是唯一的,你必須在"."操作符之前加上變量名或typedef名稱。例如,下面的兩個(gè)結(jié)構(gòu)都具有SameName這個(gè)成員變量:structFIRST_TYPE(char*pszWeasel;intSameName;};structSECOND_TYPE(intiWonton;longSameName;};如果按下面方式聲明變量:structFIRST_TYPEftTest;structSECOND_TYPEstTemp;那么,所有引用SameName成員的地方都必須使用變量名,因?yàn)镾ameName不是唯一的。另外,由于上面的pszWeasel變量具有唯一的名稱,你可以僅僅使用它的成員名稱來引用它:__asm(MOVEBX,OFFSETftTestMOVECX,[EBX]ftTest.SameName;必須使用"ftTest"MOVESI,[EBX].pszWeasel;可以省略"ftTest"}提示:省略變量名僅僅是為了書寫代碼方便,生成的匯編指令還是一樣的。5.用內(nèi)聯(lián)匯編寫函數(shù)如果用內(nèi)聯(lián)匯編寫函數(shù)的話,要傳遞參數(shù)和返回一個(gè)值都是非常容易的。看下面的例子,比較一下用獨(dú)立匯編和內(nèi)聯(lián)匯編寫的函數(shù):;PowerAsm.asm;ComputethepowerofanintegerPUBLICGetPowerAsm_TEXTSEGMENTWORDPUBLIC'CODE'GetPowerAsmPROCPUSHEBP;SaveEBPMOVEBP,ESP;MoveESPintoEBPsowecanrefer;toargumentsonthestackMOVEAX,[EBP+4];GetfirstargumentMOVECX,[EBP+6];GetsecondargumentSHLEAX,CL;EAX=EAX*(2ACL)POPEBP;RestoreEBPRET;ReturnwithsuminEAXGetPowerAsmENDP_TEXTENDSENDC/C++函數(shù)一般用堆棧來傳遞參數(shù),所以上面的函數(shù)中需要通過堆棧位置來訪問它的參數(shù)(在MASM或其它一些匯編工具中,也允許通過名稱來訪問堆棧參數(shù)和局部堆棧變量)。下面的程序是使用內(nèi)聯(lián)匯編寫的://PowerC.c#includeintGetPowerC(intiNum,intiPower);intmain()(printf("3times2tothepowerof5is%d\n",GetPowerC(3,5));}intGetPowerC(intiNum,intiPower)(__asm(MOVEAX,iNum;GetfirstargumentMOVECX,iPower;GetsecondargumentSHLEAX,CL;EAX=EAX*(2tothepowerofCL)}//ReturnwithresultinEAX}使用內(nèi)聯(lián)匯編寫的GetPowerC函數(shù)可以通過參數(shù)名稱來引用它的參數(shù)。由于GetPowerC函數(shù)沒有執(zhí)行C的return語句,所以編譯器會(huì)給出一個(gè)警告信息,我們可以通過#pragmawarning禁止生成這個(gè)警告。內(nèi)聯(lián)匯編的其中一個(gè)用途是編寫naked函數(shù)的初始化和結(jié)束代碼。對(duì)于一般的函數(shù),編譯器會(huì)自動(dòng)幫我們生成函數(shù)的初始化(構(gòu)建參數(shù)指針和分配局部變量等)和結(jié)束代碼(平衡堆棧和返回一個(gè)值等)。使用內(nèi)聯(lián)匯編,我們可以自己編寫干干凈凈的函數(shù)。當(dāng)然,此時(shí)我們必須自己動(dòng)手做一些有關(guān)函數(shù)初始化和掃尾的工作。例如:void__declspec(naked)MyNakedFunction()(//Nakedfunctionsmustprovidetheirownprolog.__asm(PUSHEBPMOVESP,EBPSUBESP,__LOCAL_SIZE}//Andwemustprovideepilog.__asm(POPEBPRET}}6.調(diào)用C/C++函數(shù)內(nèi)聯(lián)匯編中調(diào)用聲明為__cdecl方式(默認(rèn))的C/C++函數(shù)必須由調(diào)用者清除參數(shù)堆棧,下面是一個(gè)調(diào)用C/C++函數(shù)例子:#includecharszFormat[]="%s%s\n";charszHello[]="Hello";charszWorld[]="world";voidmain()(__asm(MOVEAX,OFFSETszWorldPUSHEAXMOVEAX,OFFSETszHelloPUSHEAXMOVEAX,OFFSETszFormatPUSHEAXCALLprintf//壓入了3個(gè)參數(shù)在堆棧中,調(diào)用函數(shù)之后要調(diào)整堆棧ADDESP,12}}提示:參數(shù)是按從右往左的順序壓入堆棧的。如果調(diào)用__stdcall方式的函數(shù),則不需要自己清除堆棧。因?yàn)檫@種函數(shù)的返回指令是RETn,會(huì)自動(dòng)清除堆棧。大多數(shù)WindowsAPI函數(shù)均為__stdcall調(diào)用方式(僅除wsprintf等幾個(gè)之外),下面是一個(gè)調(diào)用MessageBox函數(shù)的例子:#includeTCHARg_tszAppName[]=TEXT("APITest");voidmain()(TCHARtszHello[]=TEXT("Hello,world!");__asm(PUSHMB_OKORMB_ICONINFORMATIONPUSHOFFSETg_tszAppName;全局變量用OFFSETLEAEAX,tszHello;局部變量用LEAPUSHEAXPUSH0CALLDWORDPTR[MessageBox];注意這里不是CALLMessageBox,而是調(diào)用重定位過的函數(shù)地址}}提示:可以不受限制地訪問C++成員變量,但是不能訪問C++的成員函數(shù)。7.定義__asm塊為C/C++宏使用C/C++宏可以方便地把匯編代碼插入到源代碼中。但是這其中需要額外地注意,因?yàn)楹陮?huì)擴(kuò)展到一個(gè)邏輯行中。為了不會(huì)出現(xiàn)問題,請(qǐng)按以下規(guī)則編寫宏:使用花括號(hào)把__asm塊包圍住;把__asm關(guān)鍵字放在每條匯編指令之前;使用經(jīng)典C風(fēng)格的注釋("/*comment*/"),不要使用匯編風(fēng)格的注釋(”;comment")或單行的C/C++注釋(”//comment");舉個(gè)例子,下面定義了一個(gè)簡單的宏:#definePORTIO__asm\/*Portoutput*/\(\__asmMOVAL,2\__asmMOVDX,0xD007\__asmOUTDX,AL\}乍一看來,后面的三個(gè)__asm關(guān)鍵字好像是多余的。其實(shí)它們是需要的,因?yàn)楹陮⒈粩U(kuò)展到一個(gè)單行中:__asm/*Portoutput*/{__asmMOVAL,2__asmMOVDX,0xD007__asmOUTDX,AL}從擴(kuò)展后的代碼中可以看出,第三個(gè)和第四個(gè)__asm關(guān)鍵字是必須的(作為語句分隔符)。在__asm塊中,只有__asm關(guān)鍵字和換行符會(huì)被認(rèn)為是語句分隔符,又因?yàn)槎x為宏的一個(gè)語句塊會(huì)被認(rèn)為是一個(gè)邏輯行,所以必須在每條指令之前使用__asm關(guān)鍵字。括號(hào)也是需要的,如果省略了它,編譯器將不知道匯編代碼在哪里結(jié)束,__asm塊后面的C/C++語句看起來會(huì)被認(rèn)為是匯編指令。同樣是由于宏展開的原因,匯編風(fēng)格的注釋(”;comment")和單行的C/C++注釋("http://commen")也可能會(huì)出現(xiàn)錯(cuò)誤。為了避免這些錯(cuò)誤,在定義—asm塊為宏時(shí)請(qǐng)使用經(jīng)典C風(fēng)格的注釋("/*comment*/")。和C/C++宏一樣__asm塊寫的宏也可以擁有參數(shù)。和C/C++宏不一樣的是,__asm宏不能返回一個(gè)值,因此,不能使用這種宏作為C/C++表達(dá)式。不要不加選擇地調(diào)用這種類型的宏。比如,在聲明為__fastcall的函數(shù)中調(diào)用匯編語言宏可能會(huì)導(dǎo)致不可預(yù)料的結(jié)果(請(qǐng)參看前文的說明)。8.轉(zhuǎn)跳可以在C/C++里面使用goto轉(zhuǎn)跳到__asm塊中的標(biāo)號(hào)處,也可以在__asm塊中轉(zhuǎn)跳到__asm塊里面或外面的標(biāo)號(hào)處。__asm塊內(nèi)的標(biāo)號(hào)是不區(qū)分大小寫的(指令、指示符等也是不區(qū)分大小寫的)。例如:voidMyFunction(){gotoC_Dest;/*正確*/gotoc_dest;/*錯(cuò)誤*/gotoA_Dest;/*正確*/gotoa_dest;/*正確*/__asm(JMPC_Dest;正確JMPc_dest;錯(cuò)誤JMPA_Dest;正確JMPa_dest;正確a_dest:;__asm標(biāo)號(hào)}C_Dest:/*C/C++標(biāo)號(hào)*/return;}不要使用函數(shù)名稱當(dāng)作標(biāo)號(hào),否則將轉(zhuǎn)跳到函數(shù)中執(zhí)行,而不是標(biāo)號(hào)處。例如,由于exit是C/C++的函數(shù),下面的轉(zhuǎn)跳將不會(huì)到exit標(biāo)號(hào)處:;錯(cuò)誤:使用函數(shù)名作為標(biāo)號(hào)JNEexitexit美元符號(hào)"$"用于指定當(dāng)前指令位置,常用于條件跳轉(zhuǎn)中,例如JNE$+5;下面這條指令的長度是5個(gè)字節(jié)JMP_LabelNOP;$+5,轉(zhuǎn)跳到了這里L(fēng)abel:五、在VisualC++工程中使用獨(dú)立匯編內(nèi)聯(lián)匯編代碼不易于移植,如果你的程序打算在不同類型的機(jī)器(比如x86和Alpha)上運(yùn)行,你可能需要在不同的模塊中使用特定的機(jī)器代碼。這時(shí)候你可以使用MASM(MicrosoftMacroAssembler),因?yàn)镸ASM支持更多方便的宏指令和數(shù)據(jù)指示符。這里簡單介紹一下在VisualStudio.NET2003中調(diào)用MASM編譯獨(dú)立匯編文件的步驟。在VisualC++工程中,添加按MASM的要求編寫的.asm文件。在解決方案資源管理器中,右擊這個(gè)文件,選擇"屬性"菜單項(xiàng),在屬性對(duì)話框中,點(diǎn)擊"自定義生成步驟",設(shè)置如下項(xiàng)目:命令行:ML.exe/nologo/c/coff"-Fo$(IntDir)\$(InputName).obj""$(InputPath)"輸出:$(IntDir)\$(InputName).obj如果要生成調(diào)試信息,可以在命令行中加A"/Zi"參數(shù),還可以根據(jù)需要生成.lst和.sbr文件。如果要在匯編文件中調(diào)用WindowsAPI,可以從網(wǎng)上下載MASM32包(包含了MASM匯編工具、非常完整的WindowsAPI頭文件/庫文件、實(shí)用宏以及大量的Win32匯編例子等)。相應(yīng)地,應(yīng)該在命令行中加入"/IX:\MASM32\INCLUDE"參數(shù)指定WindowsAPI匯編頭文件(.inc)的路徑。MASM32的主頁是:,里面可以下載最新版本的MASM32包。回答者:mangohappy-經(jīng)理四級(jí)5-2513:38你寫int21H當(dāng)然不會(huì)通過了。應(yīng)該寫int0x21才對(duì)匯編和c語言如何結(jié)合的?°懸賞分:0-解決時(shí)間:2006-2-2211:06匯編和c語言如何結(jié)合的,用什莫語法?提問者:zfaaqq-見習(xí)魔法師一級(jí)最佳答案匯編語言沒有高級(jí)語言要占用較大的存儲(chǔ)空間和較長的運(yùn)行時(shí)間等缺點(diǎn),它的運(yùn)行速度快是高級(jí)語言所不能比擬的??梢哉f高級(jí)語言與匯編語言各有千秋。有時(shí)我們采用高級(jí)語言編程速度達(dá)不到要求,全部采用匯編語言編程工作量又大,此時(shí)可以采用"混合"編程,彼此相互調(diào)用,進(jìn)行參數(shù)傳遞,共享數(shù)據(jù)結(jié)構(gòu)及數(shù)據(jù)信息,是一種有效的編程方法。這種方法可以發(fā)揮各種語言的優(yōu)勢(shì)和特點(diǎn),充分利用現(xiàn)有的多種實(shí)用程序、庫程序等使軟件的開發(fā)周期大大縮短。1高級(jí)語言與匯編語言的接口需要解決的問題1、 需要說明和建立調(diào)用者與被調(diào)用者間的關(guān)系被調(diào)用的過程或函數(shù)應(yīng)預(yù)先說明為外部類型,如匯編子程序,應(yīng)用PUBLIC說明其可被外部模塊引用;調(diào)用程序則應(yīng)預(yù)先說明要引用的外部模塊名。2、 參數(shù)傳遞問題在匯編子程序之間通常采用寄存器作為參數(shù)傳遞的工具,匯編語言與高級(jí)語言程序間的參數(shù)傳遞,一般采用堆棧來傳遞,即調(diào)用程序?qū)?shù)依次壓入堆棧中,當(dāng)被轉(zhuǎn)調(diào)用程序后,再從堆棧中依次彈出參數(shù)作為操作數(shù)使用。為此,必須了解各種語言的堆棧結(jié)構(gòu)、生成方式和入棧方式等。BASIC、FORTRAN、PASCAL等語言其參數(shù)進(jìn)棧順序是與參數(shù)在參數(shù)表中出現(xiàn)的順序相同,即從右到左;而C語言則相反。2C語言與匯編語言的接口2.1C語言調(diào)用匯編子程序?在C程序中使用關(guān)鍵字"ExTERn"對(duì)函數(shù)作顯式說明。?參數(shù)傳遞順序是按其在參數(shù)表中出現(xiàn)的順序的反序被壓入堆棧中,即第一個(gè)參數(shù)最后進(jìn)入堆棧,它在棧中的地址最低。?對(duì)不同的存儲(chǔ)模式(極小、小、緊湊、中、大和巨)要選用不同的匯編語言格式,如C程序?yàn)樾∧J?,匯編用近過程,C程序?yàn)榇竽J?,匯編用遠(yuǎn)過程。?匯編程序取C的參數(shù)。遠(yuǎn)過程返回地址占四個(gè)字節(jié),BP壓入占二字節(jié),所以第一個(gè)參數(shù)在BP+6所指向的單元。對(duì)于近過程第一個(gè)參數(shù)在BP+4所指向的單元。?匯編程序中寄存器的保護(hù)。TuRboC允許子過程使用SI和DI存放局部變量,當(dāng)寄存器變量多于二個(gè)時(shí),多余部分會(huì)自動(dòng)轉(zhuǎn)到堆棧中存儲(chǔ)。因此,匯編過程的格式為:PUSHBPMOVBP,SPPUSHDIPUSHSI3POPSIPOPDIPOPBPRET?返回值。每種C數(shù)據(jù)類型都有一個(gè)標(biāo)準(zhǔn)的返回位置,一般在AX中(極小、小、中模式),DX:AX(緊湊、大、巨模式),如:chaR,unSignEdchaR,Enum,ShoRTinT等,返回值位置為AX,且返回?cái)?shù)據(jù)必須放置在RET指令之前。匯編子程序要定義為遠(yuǎn)過程,并用PUBLIC偽指令把過程名定義為公共。例:#includE"STdio.h〃#includE〃STdlib.h〃chaRMESSagE[]=〃MESSagE";inTfaRREVSTR(chaRfaRSTR);Voidmain(Void)(REVSTR((chaRfaR)MESSagE);printf(〃%S〃,MESSagE);}REVSTR.asm■■■PUBLIC-REVSTR-REVSTRPROCPUSHBPMOVBP,SPPUSHDSPUSHSIPUSHDI■■■POPSIPOPAXMOVDS,AXPOPBPMOVAX,CXRETREVSTRENDPEND2.2C語言嵌入?yún)R編在C程序中允許直接編寫匯編語言代碼,這稱作嵌入?yún)R編。C程序中嵌入?yún)R編后可以無分號(hào)(C語言的語句以分號(hào)結(jié)束,匯編語句是C語言中唯一以換行結(jié)束的語句),以關(guān)鍵詞ASM張一個(gè)嵌入?yún)R編指令,如需多個(gè)ASM語句,可以將它們放在花括號(hào)內(nèi)。如,ASMMOVAX,DX/注釋/ASMPUSHAX}/注釋/C語言允許嵌入四類匯編命令:一般指令、串指令、跳轉(zhuǎn)指令、數(shù)據(jù)分配和定義指令,嵌入?yún)R編比調(diào)用匯編子程序更方便、靈活、功能也更強(qiáng)。但嵌入?yún)R編不是一個(gè)完整的匯編程序,所以許多錯(cuò)誤不能馬上檢查出來。3結(jié)束語采用兩種或兩種以上的編程語言組合編程,彼此相互調(diào)用,進(jìn)行參數(shù)傳遞,是一種有效的程序設(shè)計(jì)方法。這種方法可以充分發(fā)揮各種語言的優(yōu)勢(shì),充分利用現(xiàn)有的實(shí)用程序,是當(dāng)前程序接口技術(shù)的一個(gè)重要研究和應(yīng)用領(lǐng)域在c語言(C++或G++)中如何嵌入?yún)R編°懸賞分:200-解決時(shí)間:2007-8-1001:05要求不斷輸入一個(gè)整數(shù)A,輸出整數(shù)A-1,如果A為0就停止.由于測(cè)試數(shù)據(jù)的數(shù)量非常大,運(yùn)行起來很慢.請(qǐng)問怎么在C中嵌套匯編來大大加大效率,編譯器是C++或G++.最好給一小段代碼樣例,我嵌套匯編總是編譯錯(cuò)誤.謝謝各位牛人了.我寫了個(gè)C語言的例子,要求嵌套匯編后功能不能變.如果輸入輸出都用匯編就更好了.(必須要VC++6.0編譯運(yùn)行才可以,LINUX的G++編譯運(yùn)行也可以)#include<stdio.h>intmain()(intn;while(scanf("%d”,&n)==1)(if(n==0)break;printf("%d\n",n-1);}return0;}我看好象嵌套了匯編效率會(huì)提高3倍到5倍左右.問題補(bǔ)充:如果可以,請(qǐng)給一小段代碼樣例(用我寫的小C程序改下就可以了.)(讀文件行不通哈.因?yàn)榇罅繑?shù)據(jù)測(cè)試本來就會(huì)用到文件輸入輸出.我要的是提高效率但不通過改程序方法,只改語言.)最好請(qǐng)用VC++6.0編譯通過...運(yùn)行輸入1000000輸出答案是不是999999.請(qǐng)不要給運(yùn)行錯(cuò)誤的答案..(范圍是INT)提問者:火領(lǐng)-見習(xí)魔法師一級(jí)最佳答案今天有點(diǎn)時(shí)間,重新改下了下,為避免因編譯器和平臺(tái)實(shí)現(xiàn)而出現(xiàn)的問題,我寫了三個(gè)版本,分別是windows下vc6.0,windows下mingw和cygwin和linux下的gcc/g++。vc6.0:#include<stdio.h>constchar*input="%d";constchar*output="%d\n";intn;5__asmleaeax,npusheaxpushinputloopx:callscanfcmpeax,1jneendmovecx,njecxzenddececxpushecxpushoutputcallprintfaddesp,8jmploopxend:55mingw/cygwin:#include<stdio.h>constchar*input="%d";constchar*output="%d\n";intn;intmain(){__asm__5"pushl$_n\n""pushl_input\n""callscanf\n"58addi$8,/oesp\n"cmpl$1,%eax\n"jneend\n""movl_n,%ecx\n'"jecxzend\n""decl%ecx\n""pushl%ecx\n""pushl_output\n""call_printf\n""addl$8,%esp\n""jmploop\n"7return0;linuxgcc/g++:#include<stdio.h>constchar*input="%d";constchar*output="%d\n";intn;intmain()(__asm__"pushl$n\n""pushlinput\n""loop:\n""callscanf\n""cmp$1,%eax\n""jneend\n""movln,%ecx\n""jecxzend\n""decl%ecx\n""pushl%ecx\n""pushloutput\n""callprintf\n""addl$8,%esp\n""jmploop\n""end:\n""addl$8,%esp\n");return0;}回答者:飄渺者間天-參將八級(jí)8-811:25評(píng)論者:sflypig-經(jīng)理四級(jí)其他回答共9條上面的仁兄mian()不是在嗎,你沒看到?VC是可以嵌入?yún)R編,可是你嵌入的是一個(gè)完整的匯編程序,這有些不合理吧.試想,如果可以嵌入完整的匯編程序,那VC豈不是可以叫VA(VisualAsm)了:)你把那些定義段的偽代碼去掉,然后將變量定義放在__asm(}前面(嵌入代碼可以訪問到這些變量的).然后再編譯,應(yīng)該沒問題了:)在VC中嵌入?yún)R編,只需在_asm(加入實(shí)現(xiàn)應(yīng)用的匯編代碼。}就行了?;卮鹫撸篽jbsahd-秀才二級(jí)7-2314:46__asm(匯編代碼}例如a+b程序intmain()(inta,b;__asm(mova,eaxaddb,eaxmoveax,a}return0;}回答者:ecchi-助理三級(jí)7-2314:51怎么利用這次回答者:金秋之韻JFSSIF-助理二級(jí)7-2314:52我不知道你的測(cè)試是干什么用的。但是想要提高效率。你可以試著把scanf和printf都改為用文件輸入輸出。你scanf不會(huì)是用手輸入的吧?估計(jì)是在一個(gè)文件中準(zhǔn)備的數(shù)據(jù)?;卮鹫撸簃essiahfree-榜眼十二級(jí)7-2315:05有沒有軟件可以潛入的回答者:wanlyn-助理三級(jí)7-2400:03把數(shù)據(jù)保存在文件里!讓c去讀文件好了嘛回答者:xuyue3000-魔法師四級(jí)7-2413:04有道理回答者:英語一級(jí)-初.入江湖二級(jí)7-3014:08高3倍到5倍左右.問題補(bǔ)充:如果可以,請(qǐng)給一小段代碼樣例(用我寫的小C程序改下就可以了.)(讀文件行不通哈.因?yàn)榇罅繑?shù)據(jù)測(cè)試本來就會(huì)用到文件輸入輸出.我要的是提高效率但不通過改程序方法,只改語言.)最好請(qǐng)用VC++6.0編譯通過...運(yùn)行輸入1000000輸出答案是不是999999.請(qǐng)不要給運(yùn)行錯(cuò)誤的答案..(范圍是INT)提問者:火領(lǐng)-見習(xí)魔法師二級(jí)答復(fù)共9條上面的仁兄mian()不是在嗎,你沒看到?VC是可以嵌入?yún)R編,可是你嵌入的是一個(gè)完整的匯編程序,這有些不合理吧.試想,如果可以嵌入完整的匯編程序,那VC豈不是可以叫VA(VisualAsm)了:)你把那些定義段的偽代碼去掉,然后將變量定義放在__asm(}前面(嵌入代碼可以訪問到這些變量的).然后再編譯,應(yīng)該沒問題了:)在VC中嵌入?yún)R編,只需在asm按照上節(jié)所論述的各種約定,讓我們編寫一個(gè)C語言程序調(diào)用匯編語言子程序的簡單例子,這里沒有參數(shù)傳遞的問題。例7.3:C語言程序調(diào)用匯編語言子程序,顯示一段信息/*C語言程序:lt703.c*/externvoiddisplay(void);/*說明display是外部函數(shù)*/main(){display();};匯編語言子程序:lt703s.asm.modelsmall,c;采用小型存儲(chǔ)模式和C語言類型.datamsgdb’Hello,CandAssembly!’,’$’.codePUBLICdisplay;指明該過程(子程序)可供外部模塊使用displayproc;采用了一致的命名約定,共用標(biāo)識(shí)符不必加下劃線movah,9;小型模式只有一個(gè)數(shù)據(jù)段,所以不必設(shè)置DSmovdx,offsetmsg;寄存器AX和DX無須保護(hù)int21hret_displayendpend上述兩個(gè)源程序文件已經(jīng)看懂了吧,那就看看應(yīng)該按照怎樣的步驟進(jìn)行編譯和連接吧:?利用匯編程序編譯匯編語言程序成為,obj目標(biāo)代碼文件,例如:ML/clt703s.asm它將生成lt703s.obj文件。ML的缺省選項(xiàng)Cx表示保持匯編語言程序中的名字的大小寫不變,這樣才能在連接時(shí)不出錯(cuò);選項(xiàng)Cu將使名字轉(zhuǎn)變成大寫,不應(yīng)使用。?利用C編譯程序編譯C語言程序成為?obj目標(biāo)代碼文件,例如:TCC-clt703.c其中,-c參數(shù)表示只是編譯、不連接,結(jié)果生成lt703.obj文件。TCC缺省采用小型存儲(chǔ)模式,若采用其他模式,要利用-m選項(xiàng);若C程序中有#include包含文件行,則需加-I選項(xiàng)。?利用連接程序?qū)⒏鱾€(gè)目標(biāo)代碼文件連接在一起,得到可執(zhí)行程序文件,例如:TLINKlib\c0slt703lt703s,lt703?exe,Jib\cs注意,直接使用TurboC的連接程序TLINK進(jìn)行連接時(shí),用戶必須指定要連接的與存儲(chǔ)模式一致的初始化模塊和函數(shù)庫文件,并且初始化模塊必須是第一個(gè)文件。上例中,lib\c0s和lib\cs就是在lib目錄下小型存儲(chǔ)模式的初始化模塊C0S.OBJ和函數(shù)庫CS.LIBo如果形成的可執(zhí)行文件lt703.exe正確,它的運(yùn)行結(jié)果將是:Hello,CandAssembly!編譯和連接也可以利用命令行一次完成,這樣更加方便。它的一般格式為:TCC-mx-I包含文件路徑-L庫文件路徑filenamelfilename2...例如,上例可以利用如下命令:TCC-ms-Iinclude-Lliblt703.clt703s.obj其中-m選項(xiàng)指定存儲(chǔ)模式,其后的字母x為t(微型)、s(小型,缺省值)、c(緊湊)、m(中型)、l(大型)、h(巨型)之一,分別代表六種存儲(chǔ)模式;-I選項(xiàng)指定連接所需的頭文件等包含文件所在的路徑;-L選項(xiàng)指定所需的初始化模塊C0X.OBJ(此處的x與存儲(chǔ)模式一樣)和函數(shù)庫的路徑;filenamel、filename2等可以是C語言源程序名、匯編語言源程序名或目標(biāo)代碼文件名,C程序擴(kuò)展名?c可以省略,但匯編源程序和目標(biāo)代碼文件的擴(kuò)展名不能省略。若有.asm文件,則TCC會(huì)自動(dòng)調(diào)用TASM.EXE對(duì).asm文件進(jìn)行匯編,因此TASM.EXE必須在當(dāng)前目錄中。若沒有TASM.EXE,也可用微軟ML.EXE(或MASM.EXE)對(duì).asm文件匯編生成目標(biāo)文件,再將目標(biāo)文件加入TCC命令行中。學(xué)會(huì)了吧?很簡單,不是嗎?C程序的編譯和模塊連接也可以在TurboC集成環(huán)境下進(jìn)行。此時(shí)需要選用一致的存儲(chǔ)模式,并建立一個(gè)工程文件,包括需編譯連接的C源文件名以及匯編語言目標(biāo)文件名。按照上節(jié)所論述的各種約定,讓我們編寫一個(gè)C語言程序調(diào)用匯編語言子程序的簡單例子,這里沒有參數(shù)傳遞的問題。例7.3:C語言程序調(diào)用匯編語言子程序,顯示一段信息/*C語言程序:lt703.c*/externvoiddisplay(void);/*說明display是外部函數(shù)*/main(){display();};匯編語言子程序:lt703s.asm.modelsmall,c;采用小型存儲(chǔ)模式和C語言類型.datamsgdb’Hello,CandAssembly!’,’$’.codePUBLICdisplay;指明該過程(子程序)可供外部模塊使用displayproc;采用了一致的命名約定,共用標(biāo)識(shí)符不必加下劃線movah,9;小型模式只有一個(gè)數(shù)據(jù)段,所以不必設(shè)置DSmovdx,offsetmsg;寄存器AX和DX無須保護(hù)int21hret_displayendpend上述兩個(gè)源程序文件已經(jīng)看懂了吧,那就看看應(yīng)該按照怎樣的步驟進(jìn)行編譯和連接吧:?利用匯編程序編譯匯編語言程序成為,obj目標(biāo)代碼文件,例如:ML/clt703s.asm它將生成lt703s.obj文件。ML的缺省選項(xiàng)Cx表示保持匯編語言程序中的名字的大小寫不變,這樣才能在連接時(shí)不出錯(cuò);選項(xiàng)Cu將使名字轉(zhuǎn)變成大寫,不應(yīng)使用。?利用C編譯程序編譯C語言程序成為?obj目標(biāo)代碼文件,例如:TCC-clt703.c其中,-c參數(shù)表示只是編譯、不連接,結(jié)果生成lt703.obj文件。TCC缺省采用小型存儲(chǔ)模式,若采用其他模式,要利用-m選項(xiàng);若C程序中有#include包含文件行,則需加-I選項(xiàng)。?利用連接程序?qū)⒏鱾€(gè)目標(biāo)代碼文件連接在一起,得到可執(zhí)行程序文件,例如:TLINKlib\c0slt703lt703s,lt703?exe,Jib\cs注意,直接使用TurboC的連接程序TLINK進(jìn)行連接時(shí),用戶必須指定要連接的與存儲(chǔ)模式一致的初始化模塊和函數(shù)庫文件,并且初始化模塊必須是第一個(gè)文件。上例中,lib\c0s和lib\cs就是在lib目錄下小型存儲(chǔ)模式的初始化模塊C0S.OBJ和函數(shù)庫CS.LIBo如果形成的可執(zhí)行文件lt703.exe正確,它的運(yùn)行結(jié)果將是:Hello,CandAssembly!編譯和連接也可以利用命令行一次完成,這樣更加方便。它的一般格式為:TCC-mx-I包含文件路徑-L庫文件路徑filenamelfilename2...例如,上例可以利用如下命令:TCC-ms-linclude-Lliblt703.clt703s.obj其中-m選項(xiàng)指定存儲(chǔ)模式,其后的字母x為t(微型)、s(小型,缺省值)、c(緊湊)、m(中型)、l(大型)、h(巨型)之一,分別代表六種存儲(chǔ)模式;-I選項(xiàng)指定連接所需的頭文件等包含文件所在的路徑;-L選項(xiàng)指定所需的初始化模塊C0X.OBJ(此處的x與存儲(chǔ)模式一樣)和函數(shù)庫的路徑;filenamel、filename2等可以是C語言源程序名、匯編語言源程序名或目標(biāo)代碼文件名,C程序擴(kuò)展名?c可以省略,但匯編源程序和目標(biāo)代碼文件的擴(kuò)展名不能省略。若有.asm文件,則TCC會(huì)自動(dòng)調(diào)用TASM.EXE對(duì).asm文件進(jìn)行匯編,因此TASM.EXE必須在當(dāng)前目錄中。若沒有TASM.EXE,也可用微軟ML.EXE(或MASM.EXE)對(duì).asm文件匯編生成目標(biāo)文件,再將目標(biāo)文件加入TCC命令行中。學(xué)會(huì)了吧?很簡單,不是嗎?C程序的編譯和模塊連接也可以在TurboC集成環(huán)境下進(jìn)行。此時(shí)需要選用一致的存儲(chǔ)模式,并建立一個(gè)工程文件,包括需編譯連接的C源文件名以及匯編語言目標(biāo)文件名。C語言編譯產(chǎn)生的.OBJ文件和匯編編譯產(chǎn)生的.OBJ文件,如何連接。懸賞分:200-解決時(shí)間:2007-6-116:30C語言程序調(diào)用匯編語言過程法:C語言程序經(jīng)編譯后產(chǎn)生.OBJ文件,匯編程序經(jīng)匯編后

溫馨提示

  • 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)論