Intel彙編指令格式解析

環境:

  win7_x64旗艦版、VS2015企業版架構

1、Intel保護模式、實地址模式和虛擬8086模式指令格式(x86)

  

                圖在Intel手冊2.1章節編碼

  1.1)Instruction Prefixes:指令前綴,可選項,每一個前綴一個字節,可選0個前綴到4個不等;指令前綴分爲四組,每組都容許設置指定的前綴代碼。spa

    Group 1:鎖定和重複前綴。操作系統

    Group 2:段覆蓋前綴。.net

    Group 3:操做數大小覆蓋前綴。3d

    Group 4:地址大小覆蓋前綴。code

  1.2)Opcode:操做碼,這是惟一不可省略的項,一、2或3個字節,在某些狀況下會有額外的三個位做爲補充opcode,這三個位是ModR/M中的Reg/Opcode域。htm

  1.3)ModR/M:一共有三個域,Mod,Reg/Opcode, R/M。blog

    Reg/Opcode在特定狀況下做爲Opcode的補充操做碼,特定狀況下做爲第一個或第二個操做數寄存器。  內存

    

    對於89 /r,Reg/Opcode表示第二個操做數寄存器,而對於8B /r,Reg/Opcode則表示第一個操做數寄存器。

    Mod域和R/M域總共5個位,定義了32種尋址方式,可選項。

  1.4)SIB:定義ModR/M的尋址方式的補充尋址方式,使用"Base + Scaled Index"格式。

  1.5)Displacement:偏移,可選,0,1,2,4個字節。

  1.6)Immediate:當即數,可選,0,1,2,4個字節。

2、IA-32e模式指令格式(x64)

  

              圖在Intel手冊2.2.1章節

  2.1)IA-32e模式有兩個子模式

    Compatibility Mode:使64位操做系統可以不加修改地運行大多數傳統保護模式軟件。

    64-Bit Mode:使64位操做系統可以運行爲訪問64位地址空間而編寫的應用程序。

  2.2)REX Preflx

     REX前綴是在64位模式下使用的指令前綴字節,與x86模式的不一樣之處就是多了這個REX Preflx,其餘基本與x86相同。

3、使用ModR/M字節的32位尋址

      圖在Intel手冊2.5.1章節Addressing-Mode Encoding of ModR/M and SIB Bytes

  解釋:

  3.1)[--][--]:表示使用SIB結構。

  3.2)disp32:表示32位偏移。

  3.3)[--][--]+disp8:表示使用SIB結構,且SIB結構後面有一個8位的偏移。

  3.4)[--][--]+disp32:表示使用SIB結構,且SIB結構後面有一個32位的偏移。

4、使用SIB字節的32位尋址

  

      圖在Intel手冊2.5.1章節Addressing-Mode Encoding of ModR/M and SIB Bytes

  SIB結構使用"Base + Scaled Index"格式。

  Base的可選值爲:

  Scaled Index的可選值爲:none、[REG]、[REG*2]、[REG*4]、[REG*8],REG爲實際的某個寄存器。

  none表示沒有Scaled Index,即Scaled Index的爲0。

  [REG]表示使用一個寄存器如[EAX]、[ECX]和[EDX]等等。

  [REG*2]表示使用寄存器乘以2如[EAX*2]、[ECX*2]和[EDX*2]等等。

5、MOVE-Move指令格式

  

                圖在Intel手冊4.3章節MOV-Move小節

  解釋:

  5.1)r:寄存器,r8表示8位寄存器,r16表示16位寄存器,r32和r64依次類推。

  5.2)m:內存地址,m8表示8位地址,m16表示16位地址,m32和m64依次類推。

  5.3)r/m:寄存器或內存

  5.4)/r:表示操做碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操做碼寄存器。

  5.4)REX:表示該操做碼有REX Preflx字段。

  5.5)REG.W:表示該操做碼有REX Preflx字段且W位值爲1。

  5.6)rb:表示使用byte寄存器,即8位寄存器。

  5.7)ib:表示使用byte當即數,即8位當即數。

  5.8)rw:表示使用word寄存器,即16位寄存器。

  5.9)iw:表示使用word當即數,即16位當即數。

  5.10)rd:表示使用dword寄存器,即32位寄存器。

  5.11)id:表示使用dword當即數,即32位當即數。

  5.12)/0:表示指定有ModR/M選項。

  完整解釋請看Intel手冊第3.1.1.1章節Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

6、ADD-Add指令格式

              圖在Intel手冊3.2章節ADD-Add小節

7、MOVSX/MOVSXD指令格式

  

      圖在Intel手冊4.3章節MOVSX/MOVSXD—Move with Sign-Extension小節

8、與之相關的註冊碼

  

  

    完整解釋請看Intel手冊第3.1.1.1章節Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

9、示例代碼分析

  9.1)示例一(x86環境)

012E17DD  8B 45 EC            mov         eax,dword ptr [ebp-14h]

  解析mov eax,dword ptr [ebp-14h]的機器代碼

    eax爲32位寄存器,[ebp-14h]是一個內存地址,因此指令應該是"MOV r32,m32",根據第五節 MOVE-Move指令格式,符合條件的只有

    

    經過8B /r進行分析

    Instruction Prefixes:該操做碼沒有Instruction Prefixes。

    Opcode:操做碼爲8B。

    ModR/M:/r表示操做碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第一個操做碼寄存器。

        第一個操做碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[ebp-14h]是相對寄存器尋址,因此Mod域爲01,R/M域爲101,最後的ModR/M爲01 000 101,即45H。

    SIB:無。
    Displacement:相對ebp寄存器的偏移爲-14h,-14h的源碼爲0001 0100,反碼爲1110 1011,補碼爲1110 1100,即EC。

    Immediate:無。

    最後的機器碼爲:8B 45 EC

 

   9.2)示例二(x86環境)

012E17E3  89 45 EC            mov         dword ptr [ebp-14h],eax  

  解析mov dword ptr [ebp-14h],eax的機器代碼

  [ebp-14h]是一個內存地址,eax爲32位寄存器,因此指令應該是"MOV m32,r32",根據第五節 MOVE-Move指令格式,符合條件的只有

  

  經過89 /r進行分析

  Instruction Prefixes:該操做碼沒有Instruction Prefixes。

  Opcode:操做碼爲89H。

  ModR/M:/r表示操做碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操做碼寄存器。

    第二個操做碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[ebp-14h]是相對寄存器尋址,因此Mod域爲01,R/M域爲101,最後的ModR/M爲01 000 101,即45H。

  SIB:無。
  Displacement:相對ebp寄存器的偏移爲-14h,-14h的源碼爲0001 0100,反碼爲1110 1011,補碼爲1110 1100,即EC。

  Immediate:無。

  最後的機器碼爲:89 45 EC

 

  9.3)示例三(x86環境)

012E17E6  01 04 8E            add dword ptr ds:[esi+ecx*4],eax

   解析add dword ptr ds:[esi+ecx*4],eax的機器代碼

  [esi+ecx*4]是一個內存地址,eax爲32位寄存器,因此指令應該是"ADD m32,r32",根據第五節 ADD-Add指令格式,符合條件的只有

  

  經過01 /r進行分析

  Instruction Prefixes:該操做碼沒有Instruction Prefixes。

  Opcode:操做碼爲01H。

  ModR/M:/r表示操做碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操做碼寄存器。

    第二個操做碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[esi+ecx*4]是寄存器間接尋址且且使用SIB結構

  

    因此Mod域爲00,R/M域爲100,最後的ModR/M爲00 000 100,即04H。

  SIB:根據[esi+ecx*4],SS爲10,Index爲001,r32爲esi寄存器即110,因此SIB爲10 001 110 = 8EH。
  Displacement:無。

  Immediate:無。

  最後的機器碼爲:01 04 8E

 

  9.4)示例四(x64環境)

000000013F3D1212 48 63 4C 24 20  movsxd rcx, dword ptr [esp+20h]

    解析movsxd rcx, dword ptr [esp+20h]的機器代碼

  rcx爲64位寄存器,[esp+20h]是一個內存地址,esp爲32位寄存器,內存地址是32位地址,因此指令應該是"movsxd r64,mr32",根據第七節 MOVSX/MOVSXD—Move with Sign-Extension指令格式,符合條件的只有

  

  經過REX.W + 63 /r進行分析

  Legacy Prefixes:無。

  REX Prefixes:REX.W表示操做碼有REX Prefixes結構,且W位爲1,則REX Prefixes爲 0100 1000,即48H。

  Opcode:操做碼爲63H。

  ModR/M:/r表示操做碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第一個操做寄存器。

    第一個操做寄存器爲rcx,根據第三節ModR/M字節的32位尋址表,Reg域爲001,[esp+20h]是相對寄存器尋址,因此Mod域爲01,表中找不到esp寄存器,因此R/M域爲100。

    

     最後的ModR/M爲01 001 100,即4CH。

  SIB:根據[--][--]+disp8能夠看出,必定有SIB結構,SIB結構爲"Base + Scaled Index",[esp+20h]沒有Scaled Index,因此SS爲00,Index爲100,Base爲esp寄存器即100,最後SIB爲00 100 100 = 24H。

  Displacement:相對esp寄存器的偏移爲+20h,+20h的補碼爲0010 0000,即20H。

  Immediate:無。

  最後的機器碼爲:48 63 4C 24 20

 

參考:

  1)[原創]X86彙編之指令格式解析:https://bbs.pediy.com/thread-191802.htm

  2)[原創]X64彙編之指令格式解析:https://bbs.pediy.com/thread-206780.htm

  3)X86指令編碼內幕 --- 指令格式:https://blog.csdn.net/xfcyhuang/article/details/6228030

  4)Intel硬編碼(一):Opcode Map、定長指令與指令前綴:https://blog.csdn.net/apollon_krj/article/details/77524601

  5)Intel硬編碼(二):不定長指令、ModR/M與SIB詳解(基於P6微架構):https://blog.csdn.net/apollon_krj/article/details/77524601

  6)Intel手冊:https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4

相關文章
相關標籤/搜索