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