資源描述:
《匯編語(yǔ)言的過(guò)程調(diào)用與c語(yǔ)言的函數(shù)調(diào)用》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫(kù)。
1、匯編語(yǔ)言的過(guò)程調(diào)用與c語(yǔ)言的函數(shù)調(diào)用姓名:孫貴森學(xué)號(hào):201212301118匯編語(yǔ)言的過(guò)程調(diào)用,如果需要傳遞參數(shù),一般有2種方法,通過(guò)寄存器來(lái)“傳遞”,或是通過(guò)參數(shù)來(lái)傳遞。(還有將所有參數(shù)制成參數(shù)列表并壓棧的傳遞方法,但較少用。)通過(guò)寄存器來(lái)“傳遞”,不是真正意義上的傳遞,其只不過(guò)是事先在幾個(gè)有限的CPU寄存器中設(shè)置相應(yīng)的值后,再調(diào)用過(guò)程,過(guò)程再直接讀取這些寄存器的內(nèi)容??上攵朔íq如C語(yǔ)言中的全局變量,極易感染。而如果通過(guò)參數(shù)來(lái)傳遞,又不得不面臨手工維護(hù)堆棧框架(stackframe)的重?fù)?dān)。堆棧框架動(dòng)態(tài)地存放著參數(shù)、調(diào)用過(guò)程的返回地
2、址、過(guò)程局部變量、過(guò)程內(nèi)的壓棧等內(nèi)容,也是不好對(duì)付的。一般情況下,一個(gè)普通的過(guò)程可能如下編寫:SumPROC?pushebp?movebp,esp?.....?popebp?retSumENDP作為遵從C調(diào)用約定(CallingConvention)調(diào)用者,則需這樣調(diào)用上述過(guò)程:push5?;push8;callSum;addesp,4*2;而如果遵從STDCALL調(diào)用約定,則:SumPROC?pushebp?movebp,esp?......?moveax,[ebp+12];?addeax,[ebp+8];?......?popebp?re
3、t4*2?;SumENDPSumPROC?pushebp?movebp,es?subesp,8?;?......?moveax,[ebp+12];?addeax,[ebp+8];?addeax,[ebp-4;?addeax,[ebp-8];?......?movesp,ebp;?pope?ret4*2;SumENDP在被調(diào)用的過(guò)程內(nèi),分為3種情況:1.無(wú)參數(shù),也無(wú)局部變量2.有參數(shù)3.有局部變量當(dāng)無(wú)參數(shù)且無(wú)局部變量時(shí),堆棧中只是保存call語(yǔ)句的下一條語(yǔ)句的地址,可以很安全地返回。而當(dāng)有參數(shù),使用PROC偽指令的接收參數(shù)的形式,MASM則會(huì)自
4、動(dòng)生成正確的返回代碼.而當(dāng)有局部變量,使用LOCAL偽指令來(lái)定義局部變量,MASM也會(huì)自動(dòng)地生成正確的返回代碼。在將參數(shù)壓棧時(shí),仍需將其打包為32位的,dataval1WORD19??;.codemovzxeax,val1;pusheax????;另一選擇是,將用作argument的變量聲明為DWORD..dataval1DWORD19;.codepushval1;還有另一種方法,即,總是傳遞指針。.dateval1WORD5val2WORD10val3WORDemainPROE?pushOFFSETval2?pushOFFSETval1?c
5、allSum???;sum(5,10)?movval3,ax??;receivethereturnvalueofSum?exitmainENDPSumPROC,?pV1:PTRWORD,?pV2:PTRWORD,?movesi,pV1?movax,wordptr[esi]?movedi,pV2?addax,wordptr[edi]?retSumENDP這種方法在保留了我們可以聲明僅需的變量類型的同時(shí),也確保argument32位的方法正確壓棧。C語(yǔ)言中的每一個(gè)函數(shù)都是一個(gè)獨(dú)立的代碼塊。一個(gè)函數(shù)的代碼塊是隱藏于函數(shù)內(nèi)部的,不能被任何其它函數(shù)中的
6、任何語(yǔ)句(除調(diào)用它的語(yǔ)句之外)所訪問(wèn)(例如,用goto語(yǔ)句跳轉(zhuǎn)到另一個(gè)函數(shù)內(nèi)部是不可能的)。構(gòu)成一個(gè)函數(shù)體的代碼對(duì)程序的其它部分來(lái)說(shuō)是隱蔽的,它既不能影響程序其它部分,也不受其它部分的影響。換言之,由于兩個(gè)函數(shù)有不同的作用域,定義在一個(gè)函數(shù)內(nèi)部的代碼數(shù)據(jù)無(wú)法與定義在另一個(gè)函數(shù)內(nèi)部的代碼和數(shù)據(jù)相互作用。C語(yǔ)言中所有的函數(shù)都處于同一作用域級(jí)別上。這就是說(shuō),把一個(gè)函數(shù)定義于另一個(gè)函數(shù)內(nèi)部是不可能的.量在函數(shù)內(nèi)部定義的變量成為局部變量。在某些C語(yǔ)言教材中,局部變量稱為自動(dòng)變量,這就與使用可選關(guān)鍵字auto定義局部變量這一作法保持一致。局部變量?jī)H由其被
7、定義的模塊內(nèi)部的語(yǔ)句所訪問(wèn)。換言之,局部變量在自己的代碼模塊之外是不可知的。括號(hào)開(kāi)始,以右花括號(hào)結(jié)束.對(duì)于局部變量,要了解的最重要的東西是:它們僅存在于被定義的當(dāng)前執(zhí)行代碼塊中,即局部變量在進(jìn)入模塊時(shí)生成,在退出模塊時(shí)消亡。定義局部變量的最常見(jiàn)的代碼塊是函數(shù)。例如,考慮下面兩個(gè)函數(shù).整數(shù)變量x被定義了兩次,一次在func1()中,一次在func2()中。func1()和func2()中的x互不相關(guān)。其原因是每個(gè)x作為局部變量?jī)H在被定義的塊內(nèi)可知。語(yǔ)言中包括了關(guān)鍵字auto,它可用于定義局部變量。但自從所有的非全局變量的缺省值假定為auto以來(lái)
8、,auto就幾乎很少使用了,因此在本書所有的例子中,均見(jiàn)不到這一關(guān)鍵字。在每一函數(shù)模塊內(nèi)的開(kāi)始處定義所有需要的變量,是最常見(jiàn)的作法。這樣做使得任何人讀此函數(shù)時(shí)都很容