青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 8  文章 - 26  trackbacks - 0
<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(5)

隨筆檔案

文章分類

文章檔案

相冊

C++語言

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

VC++內(nèi)聯(lián)匯編,將MSDN里面關(guān)于內(nèi)聯(lián)匯編的幾乎全翻譯了,一上午的成果啊,哪翻譯錯了,告我一聲啊。。。


【一】.在 __asm block中使用匯編語言

1.關(guān)鍵字__asm調(diào)用內(nèi)聯(lián)匯編語句
有三種方式可用
(1)__asm block 形式
例子:
// asm_overview.cpp
// processor: x86
void __declspec(naked) main()
{
    // Naked functions must provide their own prolog...
    __asm {
        push ebp
        mov ebp, esp
        sub esp, __LOCAL_SIZE
    }
   
    // ... and epilog
    __asm {
        pop ebp
        ret
    }
}

(2)將__asm放在每句匯編指令的開頭
例子:
__asm push ebp
__asm mov  ebp, esp
__asm sub  esp, __LOCAL_SIZE

(3)應(yīng)為__asm 也是一個語句分隔符,所以可以將匯編指令放在同一行上
例子:
__asm push ebp   __asm mov  ebp, esp   __asm sub  esp, __LOCAL_SIZE

 

2.內(nèi)聯(lián)匯編指令集
VC++編譯器支持Pentium 4 和 AMD Athlon的所有指令,額外的被其他目標(biāo)處理器支持的指令
能夠被創(chuàng)造用_emit 偽指令。
附:_emit 偽指令說明
_emit偽指令的MASM的DB指令相似,你能夠使用_emit在代碼段(text segment)的當(dāng)前位置
去定義一個字節(jié)的立即數(shù)。_emit 一次只能定義一個字節(jié),并且僅僅能夠再代碼段(text segment)
內(nèi)定義。

例子:
#define randasm __asm _emit 0x4A __asm _emit 0x43 __asm _emit 0x4B
 .
 .
 .
__asm {
     randasm
     }

3.再內(nèi)聯(lián)匯編中的MASM表達(dá)式
內(nèi)聯(lián)匯編能夠使用任何的MASM的表達(dá)式,能夠使任何操作數(shù)和操作碼的組合。

4.內(nèi)聯(lián)匯編中的數(shù)據(jù)指令和操作
盡管__asm block能夠引用C/C++的數(shù)據(jù)類型和對象(object),但是他不能定義數(shù)據(jù)對象用MASM的指令和操作,尤其,不能使用

DB,DW,DD,DQ,DT,DF 或者DUP,THIS。MASM中結(jié)構(gòu)體和記錄類型也是不可用的,內(nèi)聯(lián)匯編不接受STRUC,RECORD,WIDTH,MASK操作.

5.EVEN 和 ALIGN 指令
盡管內(nèi)聯(lián)匯編不支持大多數(shù)MASM的指令,但是支持EVEN 和 ALIGN 指令,這兩個指令填充NOP在匯編代碼中去對其數(shù)據(jù)和指定的邊界,這樣能夠

CUP的數(shù)據(jù)訪問更加高效.

6.內(nèi)聯(lián)匯編中的MASM宏指令
內(nèi)聯(lián)匯編不支持MAsm中的宏指令(MACRO, REPT, IRC, IRP, ENDM)或者宏操作符(<>, !, &, %, .TYPE)。

7.內(nèi)聯(lián)匯編中的段引用
再內(nèi)聯(lián)匯編中指定一個段只能通過寄存器,而不能通過名字(例如,段名_TEXT是不可用的),段超越必須顯式的使用寄存器,如ES:[BX].

8.內(nèi)聯(lián)匯編中的類型和變量尺寸問題
LENGTH, SIZE 和 TYPE 操作符有一個限定的意義再內(nèi)聯(lián)匯編中,他們不能被使用和DUP一起(因?yàn)樵賰?nèi)聯(lián)匯編中不能使用DUP命令),但是能夠使

用他們?nèi)サ玫紺/C++變量的尺寸和類型.
*LENGTH 操作符返回一個數(shù)組的元素數(shù)目,非數(shù)組變量返回1.
*Size 操作符返回C/C++變量的尺寸,一個變量的尺寸是LENGTH與TYPE相乘的結(jié)果.
*TYPE 操作符返回C/C++類型或變量的尺寸,如果是一個數(shù)組變量返回數(shù)組中單個元素的TYPE.

例子:
int arr[8];
__asm                   C                        Size 
LENGTH arr       sizeof(arr)/sizeof(arr[0])      8
SIZE arr         sizeof(arr)                    32
TYPE arr         sizeof(arr[0])                 4

9.內(nèi)聯(lián)匯編的注釋問題
再__asm block 中可以使用匯編語言的注釋
例子:
__asm mov ax, offset buff ; Load address of buff

【二】.再__asm block 中使用C/C++
概述:應(yīng)為內(nèi)聯(lián)匯編能夠與C/C++語句混合使用,他夢能夠使用C/C++的變量通過名字,還有C/C++語言的其他元素.
*符號,包括標(biāo)號,變量,函數(shù)名.
*常量,包括符號常量和枚舉(enum)
*宏,預(yù)處理命令
*注釋(包括 /**/和//)
*類型名稱
*typedef名稱,一般都和PTR和TYPE一起使用或者去指定結(jié)構(gòu)體或聯(lián)合成員

1.在 __asm block 中使用操作符
再 __asm block 中不能使用 C/C++特有的操作符,例如<<。C/C++與匯編共用的操作符,如*,是被解釋為匯編操作符。
舉個例子來說,[]操作符在C語言里被解釋為數(shù)組的下標(biāo), C能夠自動的轉(zhuǎn)換數(shù)組元素的尺寸,解釋為首地址+單個元素的長度*方括號內(nèi)的值.
但是再__asm block中,他被看做 MASM索引操作符(index operator),解釋為首地址+方括號中的值.
下面的實(shí)例顯示了他們的不同。
int array[10];

__asm mov array[6], bx ;  Store BX at array+6 (not scaled)

array[6] = 0;         /* Store 0 at array+24 (scaled) */

能夠使用TYPE操作符去達(dá)到和C同樣的效果
__asm mov array[6 * TYPE int], 0 ; Store 0 at array + 24

array[6] = 0;                   /* Store 0 at array + 24 */

2.使用C/C++符號在__asm block 中
__asm塊能夠引用 C/C++在作用域中的符號(包括變量名,函數(shù)名,標(biāo)號,不能調(diào)用C++的成員函數(shù))

在使用C/C++符號時有一些限制:
*每條匯編語句僅僅能夠包含一個C/C++的符號。在LENGTH, TYPE, 和 SIZE表達(dá)式中則可以使用多個C/C++符號。
*在__asm block中函數(shù)引用必須先聲明。否則編譯器不能區(qū)別在__asm block 中的標(biāo)號與函數(shù)名.
*不能使用與MASM保留字相同的符號名稱(無論大小寫)。
*結(jié)構(gòu)體和聯(lián)合類型不能別識別在__asm block中.

3.訪問C/C++數(shù)據(jù)在__asm block中
在內(nèi)聯(lián)匯編中通過名稱訪問C/C++變量是十分方便的。在__asm block中能訪問任何在作用域中符號。
例如,在其作用域中有一個C變量 var, __asm MOV EAX,var 存儲var的值在EAX中。

如果一個類,結(jié)構(gòu)體或者聯(lián)合結(jié)構(gòu)的成員是唯一的,在__asm block中引用他僅僅使用成員變量名,
而不用使用變量名或者typedef名在.操作符之前。如果成員名不是唯一的,無論如何,必須放置變量名或者typedef名在.操作符之前。
例子:
// InlineAssembler_Accessing_C_asm_Blocks.cpp
// processor: x86
#include <stdio.h>
struct first_type
{
   char *weasel;
   int same_name;
};
struct second_type
{
   int wonton;
   long same_name;
};
int main()
{
   struct first_type hal;
   struct second_type oat;
   __asm
   {
      lea ebx, hal
      mov ecx, [ebx]hal.same_name ; Must use 'hal'
      mov esi, [ebx].weasel       ; Can omit 'hal'
   }
   return 0;
}

在 __asm block中能夠訪問C++ 的數(shù)據(jù)成員而不用去遵守訪問限制,但是不能調(diào)用C++的成員函數(shù).

4.使用內(nèi)聯(lián)匯編寫函數(shù)
略。沒啥好講的,直接看例子
int power2( int num, int power )
{
   __asm
   {
      mov eax, num    ; Get first argument
      mov ecx, power  ; Get second argument
      shl eax, cl     ; EAX = EAX * ( 2 to the power of CL )
   }
   // Return with result in EAX
}

5.使用和保存寄存器在內(nèi)聯(lián)匯編中
一般來說,不應(yīng)該假設(shè)寄存器將會有一個指定的值在__asm blok塊開始時,寄存器的值不保證在離開了一個__asm block后被保存,如果你離開

了一個asm塊并開始了另一個asm塊,不應(yīng)該應(yīng)用在上一個塊中保存寄存器的值。An __asm block inherits whatever register values result

from the normal flow of control.
如果使用__fastcall調(diào)用約定,編譯器傳遞參數(shù)使用寄存器而不是堆棧,這可能產(chǎn)生一個問題在應(yīng)用了__asm block的函數(shù)中,因?yàn)楹瘮?shù)無法知

道那個參數(shù)是在寄存器中。如果一個函數(shù)接受參數(shù)在EAX中,但是過后別立刻用來存儲其他的值,那摩這個原始的參數(shù)就丟失了。并且,在

__fastcall約定中,必須保存ECX寄存器的值。
去避免如此的寄存器沖突,不要使用__fastcall調(diào)用約定為那些包含__asm block的函數(shù),如果使用/Gr編譯器選項(xiàng)指定了全局的__fastcall約定

,那摩定義每個包含__asm block的函數(shù)用_stdcall或__cdecl。
當(dāng)使用__asm去寫匯編語句在C/C++中,不需要去保存EAX,EBX,ECX,EDX,ESI,EDI。在使用EBX,ESI,EDI時,你強(qiáng)迫編譯器去保存并回復(fù)這些寄存

器的值在函數(shù)的序言與結(jié)尾處.
也應(yīng)該保存使用的其他寄存器(如DS,SS,SP,BP,EFLAGS)對于這個__asm block的作用域.
也應(yīng)該保存ESP和EBP除非你有其他的改變他們的原因。(例如,堆棧轉(zhuǎn)換)

下面這段不太好翻譯,自己看吧:
Some SSE types require eight-byte stack alignment, forcing the compiler to emit dynamic stack-alignment code. To be able to

access both the local variables and the function parameters after the alignment, the compiler maintains two frame pointers.

If the compiler performs frame pointer omission (FPO), it will use EBP and ESP. If the compiler does not perform FPO, it will

use EBX and EBP. To ensure code runs correctly, do not modify EBX in asm code if the function requires dynamic stack

alignment as it could modify the frame pointer. Either move the eight-byte aligned types out of the function, or avoid using

EBX.
注意:如果在__asm block中改變了方向標(biāo)志,通過STD,CLD,那摩就要保存這些標(biāo)志的原始值.

6.在內(nèi)聯(lián)匯編中跳轉(zhuǎn)到指定標(biāo)號
像一般的 C/C++標(biāo)號,在__asm block有函數(shù)作用域(在整個函數(shù)中可見,而不僅僅是在定義的__asm block中),匯編指令與goto語句都能跳到

標(biāo)號處.
定義在__asm block中的標(biāo)號不是大小寫敏感的,goto語句與匯編指令能夠引用整個標(biāo)號而不用考慮大小寫。但是C/C++代碼中的標(biāo)號是大小寫

敏感的當(dāng)使用goto語句時,使用匯編語句不用考慮大小寫問題.
例子:
void func( void )
{
   goto C_Dest;  /* Legal: correct case   */
   goto c_dest;  /* Error: incorrect case */

   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;
}
int main()
{
}

在__asm block中不要使用C庫的函數(shù)名作為標(biāo)號名稱。
 BAD TECHNIQUE: using library function name as label
jne exit
   .
   .
   .
exit:
   ; More __asm code follows

在MASM中($)符號作為當(dāng)前的地址計數(shù)(current location counter)。他是當(dāng)前正在被編譯的指令的標(biāo)號.在__asm block 中他的主要作用

是去作為一個長的條件跳轉(zhuǎn).
jne $+5 ; next instruction is 5 bytes long
jmp farlabel
; $+5
   .
   .
   .
farlabel:

【三】.在內(nèi)聯(lián)匯編中調(diào)用C函數(shù)
一個__asm block能夠調(diào)用C函數(shù),包括C庫函數(shù)。下面是調(diào)用printf的例子:
// InlineAssembler_Calling_C_Functions_in_Inline_Assembly.cpp
// processor: x86
#include <stdio.h>

char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";
int main( void )
{
   __asm
   {
      mov  eax, offset world
      push eax
      mov  eax, offset hello
      push eax
      mov  eax, offset format
      push eax
      call printf
      //clean up the stack so that main can exit cleanly
      //use the unused register ebx to do the cleanup
      pop  ebx
      pop  ebx
      pop  ebx
   }
}

【四】.定義__asm block作為宏
C語言的宏提供了一個簡便的方式去插匯編代碼進(jìn)入源代碼。但是那需要額外的小心因?yàn)楹瓯粩U(kuò)展到一個單獨(dú)的邏輯行上(a single logical

line),去創(chuàng)建無錯誤的宏,應(yīng)遵守下列規(guī)則:
*用{}包圍__asm block
*放__asm 關(guān)鍵字在每條匯編指令的開頭
*使用老式的注釋(/**/)代替匯編中的注釋(;)和單行注釋(//).

例子:
#define PORTIO __asm      \
/* Port output */         \
{                         \
   __asm mov al, 2        \
   __asm mov dx, 0xD007   \
   __asm out dx, al       \
}

一個__asm block寫的宏能夠帶參數(shù),但是不能返回值,因此不要使用這樣的宏在C/C++表達(dá)式中.

【五】.內(nèi)聯(lián)匯編的優(yōu)化問題
__asm block的存在會對優(yōu)化產(chǎn)生一些影響。首先,編譯器不會嘗試去優(yōu)化__asm block中的指令。第二,__asm block會對寄存器變量的存儲產(chǎn)

生影響,編譯器會避免去登記穿越__asm block的那些寄存器會被修改的變量.

posted on 2008-12-21 17:07 楊彬彬 閱讀(9314) 評論(1)  編輯 收藏 引用

FeedBack:
# re: VC++內(nèi)聯(lián)匯編(MSDN相關(guān)內(nèi)容完整翻譯) 2011-04-26 14:23 5545645
謝謝  回復(fù)  更多評論
  

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              国产精品99久久久久久久女警| 欧美一区二区在线看| 欧美日韩午夜| 国产精品v亚洲精品v日韩精品| 欧美日本乱大交xxxxx| 欧美人成在线视频| 国产精品jizz在线观看美国 | 亚洲国产日韩精品| 欧美成人亚洲| 亚洲人成小说网站色在线| 亚洲裸体俱乐部裸体舞表演av| 亚洲国产专区校园欧美| 夜夜嗨av一区二区三区中文字幕 | 亚洲美女免费精品视频在线观看| 亚洲精品一区二区网址| 99亚洲精品| 久久成人免费网| 欧美激情一区在线| 国产欧美精品| 亚洲精品1区2区| 亚洲自拍电影| 美女精品国产| 亚洲视频一区| 老司机久久99久久精品播放免费| 欧美日韩色婷婷| 一区二区三区在线免费播放| 一区二区欧美日韩| 久久躁狠狠躁夜夜爽| 日韩五码在线| 久久综合九色综合欧美就去吻| 欧美午夜片在线观看| 国产视频在线观看一区二区三区| 亚洲精品韩国| 久久综合九色| 亚洲欧美日韩另类| 欧美激情麻豆| 在线观看日韩www视频免费| 亚洲欧美日本在线| 欧美大色视频| 欧美一区二区三区男人的天堂 | 亚洲精品一区二区三区福利| 欧美亚洲综合久久| 欧美全黄视频| 91久久在线| 久久婷婷av| 一区二区三区欧美日韩| 欧美不卡在线视频| 国产一区二区黄| 亚洲一区国产视频| 亚洲精品男同| 欧美高清在线精品一区| 伊人春色精品| 美国十次成人| 久久久人成影片一区二区三区观看| 欧美午夜一区二区三区免费大片 | 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲三级观看| 欧美成人高清视频| 欧美一区日韩一区| 国产一区二区三区免费不卡| 午夜国产精品影院在线观看| 一本大道久久a久久精品综合 | 黄色免费成人| 久久永久免费| 久久免费少妇高潮久久精品99| 狠狠噜噜久久| 欧美99在线视频观看| 久久久视频精品| 亚洲人成绝费网站色www| 欧美激情按摩| 欧美裸体一区二区三区| 中文国产一区| 亚洲一级在线观看| 国产精品资源| 久久一区免费| 欧美成人免费在线观看| 99精品热视频| 一本高清dvd不卡在线观看| 欧美日韩免费观看一区二区三区 | 欧美福利影院| 欧美激情国产日韩| aⅴ色国产欧美| 一区二区三区视频在线观看| 国产精品一级| 亚洲免费中文字幕| 欧美jjzz| 另类亚洲自拍| 欧美另类变人与禽xxxxx| 欧美日韩美女在线| 夜夜嗨av一区二区三区网页| 亚洲国产高清一区二区三区| 欧美a级片网站| 日韩一区二区精品在线观看| 日韩小视频在线观看| 国产精品天美传媒入口| 久久性天堂网| 国产精品成人久久久久| 久久久久久久久一区二区| 老牛国产精品一区的观看方式| 一区二区电影免费观看| 亚洲欧美一区二区三区在线| 1204国产成人精品视频| 一本色道久久综合狠狠躁的推荐| 国产日韩欧美精品一区| 亚洲人屁股眼子交8| 国产一区二区日韩| 日韩视频免费观看高清完整版| 国产日韩av一区二区| 亚洲人成久久| 国内视频一区| 亚洲一区二区在线免费观看视频| 国产一区二区三区在线观看网站| 亚洲国产精品久久久久秋霞蜜臀| 国产女人aaa级久久久级| 亚洲娇小video精品| 激情成人亚洲| 久久成人精品一区二区三区| 午夜精品久久久久久久蜜桃app| 欧美aⅴ99久久黑人专区| 久久久综合网站| 国产精品私拍pans大尺度在线| 亚洲免费电影在线观看| 亚洲欧洲在线播放| 久久久久久成人| 久久精品国产99精品国产亚洲性色 | 久久精品五月| 亚洲女人天堂av| 欧美日本韩国一区二区三区| 女同一区二区| 在线成人h网| 久久精品91久久久久久再现| 欧美在线free| 国产日韩欧美在线视频观看| 亚洲欧美激情视频| 亚洲欧美日韩系列| 欧美视频在线观看免费网址| 99精品久久免费看蜜臀剧情介绍| 亚洲精品乱码久久久久久日本蜜臀 | 尤物九九久久国产精品的特点| 欧美激情91| 欧美日韩国产色视频| 免费在线欧美黄色| 久久久久国产精品一区三寸| 国产精品久久久久久亚洲毛片 | 欧美韩国在线| 精品二区久久| 免费欧美日韩国产三级电影| 麻豆精品在线视频| 亚洲国产日韩一区| 欧美激情亚洲| 亚洲图片欧美日产| 香蕉av777xxx色综合一区| 国产精品日韩欧美综合| 欧美在线一二三区| 麻豆精品视频| 日韩一级在线| 国产精品久久9| 亚洲综合电影| 欧美~级网站不卡| 日韩一区二区精品视频| 欧美日韩国产不卡| 一区二区三区四区五区视频| 亚洲欧美日韩精品综合在线观看| 国产精品日韩精品欧美在线| 欧美一区二区视频在线| 麻豆乱码国产一区二区三区| 亚洲国产高清高潮精品美女| 欧美日韩亚洲一区三区 | 亚洲精品乱码久久久久久| 欧美成人精品在线| 亚洲精选成人| 快播亚洲色图| 亚洲综合色自拍一区| 一区二区在线观看视频在线观看| 欧美二区在线看| 午夜视频在线观看一区二区| 欧美激情精品久久久久久蜜臀 | 亚洲另类视频| 久久久久久国产精品mv| 日韩天堂在线视频| 国产婷婷色综合av蜜臀av| 欧美激情免费观看| 久久成人免费| 亚洲影视九九影院在线观看| 亚洲激情视频| 久久久国产成人精品| 亚洲一二三四久久| 亚洲国产第一页| 国产在线播放一区二区三区 | 亚洲黄色天堂| 国产视频一区三区| 国产精品高清在线| 欧美精品videossex性护士| 久久国产视频网站| 夜夜精品视频一区二区| 亚洲福利视频网| 欧美成人精品在线视频| 久久精品国产久精国产思思| 一区二区三区|亚洲午夜| 亚洲高清在线精品|