欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
內聯(lián)匯編基礎知識
作者:釋雪
幾天看了孫原等幾位仁兄關(guān)于匯編語(yǔ)言的幾篇文章,頗感興趣。于是查了查98版的MSDN中,其中也有幾篇關(guān)于內聯(lián)匯編的基礎,索引字是asm。講得不算太難,于是試著(zhù)將其內容寫(xiě)下來(lái)了,特此貼來(lái)。
 一、 內聯(lián)匯編簡(jiǎn)述
Visual C++ 6.0編譯器下,內聯(lián)匯編可以使用所有的Intel486處理器指令集。而且可以對目標處理器建立起偽指令來(lái)實(shí)現附加指令功能。內聯(lián)匯編可以使用MASM編譯器所允許的表達式,其中的一些表達式可以通過(guò)操作符和操作數的組合,對單精值進(jìn)行運算.
雖然內聯(lián)匯編可以訪(fǎng)問(wèn)C\C++中的數據變量以及類(lèi)對象,但它不可能通過(guò)MASM指令和操作符來(lái)定義數據及對象。尤其你還不能使用DB, DW, DD, DQ, DT和DF等定義指令以及DUP和This操作符。匯編中的結構記錄也不是可用的。內聯(lián)匯編也不支持directives STRUC, RECORD, WIDTH, 和 MASK指令。不過(guò),在內聯(lián)匯編可以使用到一個(gè)_emit宏指令,它類(lèi)似于MASM中的DB指令,它可以在本區域內定義出一個(gè)字節型,雖然它每次只能定義一個(gè)字節出來(lái),但還是可以用它來(lái)定義出一個(gè)字符串,請看示例: 
#define randasm __asm _emit 0x4A __asm _emit 0x43 __asm _emit 0x4B …__asm { randasm}雖然內聯(lián)匯編不支持MASM中的很多指令,但它支持EVEN 和 ALIGN指令。它們被用于那些需要使用align labels來(lái)指定分界線(xiàn)的匯編指令。
內聯(lián)匯編不可以是一個(gè)宏匯編程序,你不可以使用MASM中的宏定義指令以及宏操作符。但內聯(lián)匯編是可以使用C\C++中的預理指令來(lái)定義宏。
在處理段時(shí),你只能使用寄存器,而不是通過(guò)名字,因為在內聯(lián)匯編中這是非法的。而且段必須顯式地使用寄存器,如: ES:[BX]
在內聯(lián)匯編使用操作符LENGTH, SIZE, 和 TYPE可以來(lái)對變量以及類(lèi)型進(jìn)行長(cháng)度的測量,你可以使用它們來(lái)求得C\C++中的變量及類(lèi)型的長(cháng)度:
*LENGTH操作符可以返回在一個(gè)變量數組中的元素個(gè)數,如果返回為1則代表這不是一個(gè)變量數組。
*SIZE操作符可以求得一個(gè)變量及類(lèi)型的總長(cháng)度。這個(gè)值也可以由LENGTH與TYPE積來(lái)求得。
*TYPE操作符可以求得一個(gè)變量及類(lèi)型的長(cháng)度,與SIZE不同的是,如果變量名是一個(gè)數組的話(huà),則返加這個(gè)數組中單個(gè)元素的長(cháng)度。
具體情況請看下表:
__asmCSize
LENGTH arrsizeof(arr)/sizeof(arr[0])8
SIZE arrsizeof(arr)16
TYPE arrsizeof(arr[0])2
包含著(zhù)內聯(lián)匯編的程序可以使用/Zi選項編譯,從而來(lái)進(jìn)行代碼級的調試工作。這樣,你就可以同時(shí)在C\C++程序段與內聯(lián)匯編段中設置斷點(diǎn),如果你使用/Fas選項允許混合匯編與C\C++源程序調試方式,那么你就可以看到混合著(zhù)匯編與源程序的代碼集合。
Visual C++編譯器允許你在內聯(lián)匯編程序中使用Intel處理器的MMX指令集。不過(guò)如果使用MMX指令集編譯器會(huì )發(fā)生警告。更多的信息請查看MSDN的Web站點(diǎn)。
 二、 關(guān)于內聯(lián)匯編的具體使用說(shuō)明: 
因為內聯(lián)匯編不需要編譯與鏈接過(guò)程,因此它比一個(gè)匯編程序更為方便。由于它能夠訪(fǎng)問(wèn)C\C++中的變量及函數,所以它能夠更好和你C\C++代碼融為一體。內聯(lián)匯編可以在以下方面進(jìn)行編程:
*用匯編語(yǔ)言編寫(xiě)函數。
*使用匯編語(yǔ)言來(lái)產(chǎn)生速度最優(yōu)化代碼段。
*直接使用匯編語(yǔ)言來(lái)對硬件進(jìn)行訪(fǎng)問(wèn)。
*為naked函數調用編寫(xiě)保護現場(chǎng)和恢復現場(chǎng)代碼( prolog and epilog code)
如果你計劃在不同機器上運行程序的話(huà),那么你應該分別放置不同機種的專(zhuān)一匯編代碼。因為內聯(lián)匯編有一定的機器專(zhuān)一性,它不完全支持所有MASM中的宏與數據類(lèi)型。
VC不支持C++中的asm關(guān)鍵字,所以你需要使用__asm(兩個(gè)下劃線(xiàn))關(guān)鍵字來(lái)編寫(xiě)你的內聯(lián)匯編代碼。
你可以使用這個(gè)關(guān)鍵字來(lái)編寫(xiě)一個(gè)內聯(lián)代碼段,如:
__asm{ mov al, 2 mov dx, 0xD007 out al, dx}也可以只編寫(xiě)一行式的內聯(lián)代碼,如:__asm mov al, 2__asm mov dx, 0xD007__asm out al, dx以上兩段代碼是同義的。但是第一種寫(xiě)法比較有好處(advantages?),它可以與C源碼明顯的區別開(kāi)來(lái),而且避免重復輸入不必要__asm關(guān)鍵字。 在內聯(lián)匯編代碼段中以下的C語(yǔ)言元素是可以被應用的:
*符號,包括跳轉標簽,變量名和函數名。(所使用C\C++符號必須在其使用名域之內。)
*C\C++常量,包括const符號化常量和共用體(enum)中的常量
*宏以及預處理表達式。
*C\C++風(fēng)格的注釋,//,/*,*/
*類(lèi)型名
*typedef定義的類(lèi)型名
 三、在內聯(lián)匯編代碼中使用C操作符
在內聯(lián)匯編中不能使用C\C++專(zhuān)有的操作符,諸如:<<,雖然,有一些操作符是MASM與C中都在使用的,比如:*操作符。但在內聯(lián)匯編中被優(yōu)先解釋為匯編操作符。例如,在C中方括號是用來(lái)訪(fǎng)問(wèn)數組的元素的。C將它解釋為首地址+單個(gè)元素長(cháng)度*元素序號。而在內聯(lián)匯編中,則將它解釋為首地址+方括號中定義的數量。是對一個(gè)地址的字節偏移量。這一點(diǎn)是在編程中應該特注意的。所以以下這一段代碼是錯誤的
 
int array[10];__asm mov array[6], 0 ; 期望達到C中的array[6] = 0功能,但這是錯誤的。正確的代碼如下:__asm mov array[6 * TYPE int], 0 ; array[6] = 0;在內聯(lián)匯編中使用C\C++符號(如前面如述,符號包括常量名,變量名,函數名以及跳轉標簽)應注意以下幾點(diǎn):
*所使用C\C++符號必須在其使用名域之內。
*一般的情況下,一句匯編語(yǔ)句只允許出現一個(gè)C\C++符號。在LENGTH, TYPE, 和 SIZE表達式中則可以使用多個(gè)C\C++符號。
*就像C語(yǔ)言一樣,在內聯(lián)匯編中調用函數之前,必須顯式的聲明函數。否則編譯器將會(huì )報錯。
*注意在內聯(lián)匯編中不能使用那些與MASM中保留字相同的C\C++符號。
*注意C\C++中的類(lèi),結構體以及共用體在內聯(lián)匯編中不直接使用。
下面將舉幾個(gè)關(guān)于使用C\C++符號的例子。
如果先前C已經(jīng)定義了一個(gè)變量var,那么則內聯(lián)匯編可以訪(fǎng)問(wèn)這個(gè)變量如下:__asm mov eax, var ;將變量var中的值賦給eax寄存器中。如果有一個(gè)結構體first_type和一個(gè)實(shí)例hal:struct first_type{ char *weasel; int same_name;} hal;在訪(fǎng)問(wèn)hal對象時(shí),則必須如下:__asm{ mov ebx, OFFSET hal ;取得hal對象的首地址 mov ecx, [ebx]hal.same_name ;加上same_name偏移值,則可以訪(fǎng)問(wèn)到成員same_name mov esi, [ebx]hal.weasel ;加上weasel偏移值。}下面是一個(gè)內聯(lián)匯編如何實(shí)現一個(gè)函數的例子:#include <stdio.h>int power2( int num, int power );void main( void ){ printf( "3 times 2 to the power of 5 is %d\n", power2( 3, 5) );}int power2( int num, int power ){ __asm { mov eax, num ; 取得第一個(gè)參數 mov ecx, power ; 取得第二個(gè)參數 shl eax, cl ; EAX = EAX * CL } //在函數中,返回值是由eax負責往回傳遞的。(順便問(wèn)一句ax與eax有什么不同啊?是不是一樣的?)}因為內聯(lián)函數中沒(méi)有return,所以在上面的例子中,編譯器會(huì )報出警告。還好,不像Java一樣,少一個(gè)多一個(gè)return都會(huì )編譯不通過(guò)。你可以使用宏#pragma warning來(lái)關(guān)掉警告器。在pascall式函數中堆棧的復位是由函數負責的,而不是調用者。在上面的例子中,由是在C函數中內部嵌入匯編來(lái)完成匯編函數的。在C函數出口處,C編譯器會(huì )自動(dòng)添加復棧指令,而不必自己添寫(xiě)。那反而會(huì )使系統混亂. 在內聯(lián)匯編中跳轉指令(包括條件跳轉),可以跳轉到C語(yǔ)言goto能到的所有地方。Goto也可以跳到內聯(lián)匯編中定義的標簽,示例如下:void func( void ){ goto C_Dest; /* Legal: correct case */ goto c_dest; /* Error: incorrect case在C中大小寫(xiě)區分。*/ goto A_Dest; /* Legal: correct case */ goto a_dest; /* Legal: incorrect case */ __asm { jmp C_Dest ; Legal: correct case jmp c_dest ; Legal: incorrect case jmp A_Dest ; Legal: correct case jmp a_dest ; Legal: incorrect case a_dest: ; __asm label } C_Dest: /* C label */ return;}另外,在給標簽起名時(shí)盡量避免與C內部的或已經(jīng)使用了的標簽名重名,如果那樣的將會(huì )出現災難性的程序錯誤。因此,在起名時(shí)最好追查一下是否這個(gè)名字已經(jīng)被使用了。 在引用函數時(shí),應注意參數的從右向左方向地壓棧。比如有一個(gè)函數是 int CAdd (int a,int b) 則應該如此調用:__asm{ mov eax,2; push; 參數b等于2 mov eax,3; push; 參數a等于3 call CAdd;調用CAdd函數 mov Result,eax;所有函數的返回值都被存放在eax。于是,Result等于5}注意內聯(lián)匯編無(wú)法調用重載函數,因為被重載函數名與原函數名不一樣。所以如果你需求調用的話(huà), (我記得vckbase中有關(guān)于重載函數的文章),就不要定義重載函數,且C++函數必須使用extern "C"關(guān)鍵字來(lái)定義。 因為C中的預處理指令#define是字符代換,所以你可以使用#define來(lái)定義一個(gè)匯編宏,例如:#define PORTIO __asm /* Port output */ { __asm mov al, 2 __asm mov dx, 0xD007 __asm out al, dx }以上,就是內聯(lián)匯編的基本使用描述。由于,本人的英文并不是太好,所以寫(xiě)出來(lái)的文章有些不連續,而且大部分話(huà)是我自己說(shuō)的,或許還會(huì )譯錯的地方,還請大家指教見(jiàn)諒。 以下是我自己寫(xiě)的一段關(guān)于類(lèi),結構體的示例:#include <iostream.h>struct MyData{ int nMember1; int * lpMember2;}; void main(){ MyData sample; __asm//這是對成員變量賦值 { mov eax,12; mov sample.nMember1,eax; } cout <<sample.nMember1<<endl; __asm//這是對成員指針賦值 { lea eax,sample.nMember1; mov sample.lpMember2,eax; } cout <<*sample.lpMember2<<endl; __asm//這是對指針所指向的變量賦值 { mov ebx,sample.lpMember2; mov eax,5; mov [ebx],eax; } cout <<sample.nMember1<<endl;}不過(guò),對于成員函數的調用仍沒(méi)有成功。請各位高手幫忙解決這個(gè)問(wèn)題。謝謝。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
(轉)Visual C Inline ASM 內聯(lián)匯編
VC++內聯(lián)匯編(MSDN相關(guān)內容完整翻譯)
程序中嵌入匯編的實(shí)例
在Visual C++中使用內聯(lián)匯編
x86匯編與C的關(guān)系
Visual C++中調用匯編語(yǔ)言的研究與實(shí)現
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久