美文网首页
指令集编码与解析

指令集编码与解析

作者: onedam | 来源:发表于2020-10-26 17:50 被阅读0次

    JVM---汇编指令集

    apt install radar2
    rasm2 -L    #查看architectures
    rasm2 -a x86 -b 32 'mov eax, 33'    #转机器码
    echo 'push eax;nop;nop' | rasm2 -f -   
    
    rasm2 -a x86 -d 55  #转汇编 push ebp
    
    rasm2 -L    #列出架构
    rasm2 -a x86 -b 32 'mov eax, 33'    #汇编
    rasm2 -a x86 -b 32 -d '90'  #反汇编
    

    rasm2 -a riscv -d b70701001307a00ab7366e01

    lui a5, 0x10
    li a4, 170
    lui a3, 0x16e3
    

    radar2当前不支持 riscv 的反汇编 rasm2 -a riscv "lui a5, 0x10" 会报错

    root@hasee-pc:~# rasm2 -a x86  -d 8b07
    mov eax, dword [edi]
    root@hasee-pc:~# rasm2 -a x86  -d 2e8b07
    mov eax, dword cs:[edi]
    root@hasee-pc:~# rasm2 -a riscv  -d 4040
    lw s0, 4(s0)
    root@hasee-pc:~# rasm2 -a x86 -d 52f30f1005062e00005049
    push edx
    movss xmm0, dword [0x2e06]
    push eax
    dec ecx
    

    指令 不要拘泥于 字节 8位的概念. 指令中的 每一个bit 都有其意义... (good) 例如
    risc-v 32位 指令划分域的时候, 7bit 3bit 5bit 12bit...等为一组...

    image.png image.png
    image.png

    R 型指令


    image.png

    I型指令


    image.png

    L型指令


    image.png image.png

    指令执行


    image.png image.png image.png

    分支跳转指令


    image.png image.png

    Opcode 对指令提供操作码,ModRM 最主要作用是对指令的 operands 提供寻址,另一个作用是对 Opcode 进行补充,而 SIB 则是对 ModRM 进行补充寻址

    有两种情况下是无需用 ModRM 提供寻址的:
    (1)一部分操作数是寄存器的,它直接嵌入 Opcode 中。

    (2)一部分操作数是立即数的,它直接嵌入指令编码中。

    image.png
    image.png
    image.png image.png image.png

    2.3 ModR/m说明 https://cloud.tencent.com/developer/article/1444066

    ModR/m
    里面分为三部分

    Mod 表示寄存器的寻址方式.

    Reg/opcode 表示寄存器或者OpCode的编码

    R/M 表示汇编中第一个寄存器的编码.

    Mod 代表寻址方式 2位表示

    00 寄存器间接寻址

    01 寄存器相对寻址偏移

    10 寄存器先对寻址偏移

    11 寄存器直接寻址

    其它寻址方式放在SIB里面

    Reg/Opcode 代表指令,
    如 mov [ebp - 38h],eax. 那么就代表eax的编号
    有时候表示寄存器,有时候表示Opcode

    R/M 表示汇编的第一个寄存器
    如 mov[ebp - 38h],eax 代表的是ebp

    2.4 SIB说明
    SIB 占一个字节.可能有可能没有,是对ModR/M寻址的补充.

    一条汇编指令

    实现自己的指令集

    https://blog.csdn.net/qq_36320285/article/details/84335674

    image.png

    wl 原来在前缀 prefix里 ..

    image.png

    ModR/M,SIB编码的含义

    让我们从最经常用到的域开始学起——ModR/M。
    在开始之前,先来讲一些最基础的概念。
    一个字节如果被转换成二进制,则是由8位(bit)来表示(不足8位的话则高位用0来补足),
    例如:16进制 2进制
    B7 1011 0111 3A 0011 1010
    示例中的B7的二进制是1011 0111,

    这是典型的4:4表示格式——1011表示的是B,0111表示的是7,
    这样,1011 0111表示的就是B7了。
    那么我们可不可以用另外一种方式来表示一个字节呢?
    答案是肯定的:16进制 2进制的4:4格式
    2进制的2:3:3格式
    B7 1011 0111 10 110 111 3A 0011 1010 00 111 010 请看,

    我们在这里引进了一种新的表示格式:2:3:3它的特点是把一个字节的8位二进制分成3个部分:
    最高的2位表示的是一个东西,接下来的3位表示的是另外一个东西,
    以及最后的3位表示的是另另外一个东西。

    好了,明白了这一点后,我们来开始吧!

    首先回忆一下OpCode的组成格式:Prefixes code ModR/M SIB Displacement Immediate

    请注意第三项:ModR/M,它占一个字节,其格式为:7 6 5 3 2 0 Mod Reg/Opcode R/M 可见,ModR/M是由Mod、Reg/Opcode和R/M三个部分组成的。

    每个部分所占的bit大小为: Mod: 占最高位的6~7共2个bit

    Reg/Opcode: 占中间位的3~5共3个bit

    R/M: 占最低位的0~2共3个bit

    呵呵,正好是2:3:3的格式!

    ModR/M的具体描述如下面两个表,第一个是16位的,第二个是32位的:(截图自《IA-32 Intel Architecture Software Developer's Manual Volume 2: Instruction Set Reference》,页码2-5,2-6)- 16位 -- 32位 -

    让我们来举个例子看看ModR/M到底是怎么来看的:
    mov edi, ecx 8B F9 sub edi, ecx 2B F9

    注意这两个OpCode的第二个字节——都是F9,再来看看OpCode的格式:Prefixes Code ModR/M SIB Displacement Immediate 我们在前面说过,在OpCode的格式中,只有Code是必须有的,别的都是可选的。

    所以,在8B F9和2B F9这两组OpCode中,8B和2B就是Code,
    (这里没有Prefixes,因为Prefixes只有在前面的章节中所介绍过的那几个:66、67、F2、F3、2E、36、3E、26、64、65、F0)。

    紧接着在Code后面的就是ModR/M了,所以在这两组OpCode中的F9就是ModR/M。(在这里也没有SIB、Displacement和Immediate)

    F9的4:4格式的二进制是1111 1001,我们把它分解成2:3:3的二进制看看:

    16进制 2进制的2:3:3格式 F9 11 111 001 也就是:
    Mod: 11
    Reg/Opcode: 111
    R/M: 001

    假设是在32位模式下。从上面的第二个图中可以看到,Mod总共分为00、01、10、11四种情况,每种情况又分别有8种情况。现在Mod是11,所以我们应该看Mod为11的那一栏。
    OK,现在来讨论第二个:Reg/OpcodeReg/Opcode中间的那个“/”表示“或”,意思就是,这个地方可以表示为Reg或者Opcode——至于到底什么时候表示Reg,什么时候表示Opcode,这就要由Code来决定了。目前我们不必去深究它,后面会讲明白的,我们只要知道,如果它是表示Opcode,则这个指令必定是2个字节的。

    Reg由3个bit的二进制组成,因此,它可以表示:2 ^ 3 = 8 一共8种可能的值。我们知道,常用的通用寄存器恰好也有8个,

    因此,根据组合数学的常识,可以得到:REG && Register REG Register 000 EAX 001 ECX 010 EDX 011 EBX 100 ESP 101 EBP 110 ESI 111 EDI 这是在32位的模式下得到的。

    在16位的模式下,Reg则是表示另外一种“局部”的格式,它的低4位表示寄存器的低地址,高4位表示寄存器的高地址,

    如下表:REG && Register REG Register 000 AL 001 CL 010 DL 011 BL 100 AH 101 CH 110 DH 111 BH 好了,把目光返回到上面的32位ModR/M图,看看最上面,在r32(/r)那一栏中,REG=111表示的就是寄存器EDI到目前为止,最后剩下还没讨论的就是R/M。

    这一栏要与Mod结合起来。我们来看Mod为11的那一栏——R/M为001对应的寄存器是ECX好了!大功告成!
    整理如下: Mod: 11 表示应该查看Mod为11的那一栏 Reg/Opcode: 111 表示的是寄存器EDI R/M: 001 表示的是ECX 因此,通过OpCode:8B F9 2B F9 不难得到:mov edi, ecx 8B F9 sub edi, ecx 2B F9

    (注:8B是助记符“MOV”的Code,2B是助记符“SUB”的Code)

    x86指令解析较好的

    displacement 规则 由 mod/r 来确定

    解析变长指令 规则

    image.png

    x86前缀 目前只有固定的11个

    呵呵不要紧,让我们来举个例子看看ModR/M到底是怎么来看的:

    mov edi, ecx 8B F9
    sub edi, ecx 2B F9

    注意这两个OpCode的第二个字节——都是F9,再来看看OpCode的格式:

    Prefixes Code ModR/M SIB Displacement Immediate

    我们在前面说过,在OpCode的格式中,只有Code是必须有的,别的都是可选的。所以,在8B F9和2B F9这两组OpCode中,8B和2B就是Code,(这里没有Prefixes,因为Prefixes只有在前面的章节中所介绍过的那几个:66、67、F2、F3、2E、36、3E、26、64、65、F0)。

    紧接着在Code后面的就是ModR/M了,所以在这两组OpCode中的F9就是ModR/M。(在这里也没有SIB、Displacement和Immediate)

    F9的4:4格式的二进制是1111 1001,我们把它分解成2:3:3的二进制看看:

    16进制 2进制的2:3:3格式
    F9 11 111 001

    也就是:

       Mod: 11
    

    Reg/Opcode: 111
    R/M: 001

    晕头转向了?呵呵,让我们来对其分而治之吧!

    Practice Makes Perfect!

    怎么判断是不是前缀指令呢?

    前缀指令就几个,很好确定,根据指令的内容来确定

    2、前缀指令是分组的:

    前缀指令最多是4个,每组一个

    <1>LOCK 和REPEAT前缀指令:

    LOCK F0 //锁地址总线的 在同一时刻只能有一个核的CPU来读取那条指令,这个指令在多核下才有意义

    REPNE/REPNZ F2 //重复执行 当zf是0的时候执行

    REP/REPZ F3 //重复执行 当zf是1的时候执行

    <2>段前缀指令:

    CS(2E)、SS(36)、DS(3E)、ES(26)、FS(64)、GS(65) //存在的意义是可以改变寻址时候的段寄存器

    <3>操作数宽度前缀指令: //操作数的宽度默认是32位,加上66,操作数的宽度就编程了16位

    66 //操作数的宽度默认是16位,加上66,操作数的宽度就编程了32位

    **<4>地址宽度前缀指令: ** //改变寻址方式的 ,这个前缀指令也是双向的

    67

    image image

    3、前缀指令最多占4个字节,最少占0个字节

    每组最多一个,可以组合使用,没有顺序问题

    Intel汇编指令格式解析

    环境:

    win7_x64旗舰版、VS2015企业版

    一、Intel保护模式、实地址模式和虚拟8086模式指令格式(x86)

    image

    图在Intel手册Volume2 2.1章节

    1.1)Instruction Prefixes:指令前缀,可选项,每个前缀一个字节,可选0个前缀到4个不等;指令前缀分为四组,每组都允许设置指定的前缀代码。

    Group 1:锁定和重复前缀。

    Group 2:段覆盖前缀。

    Group 3:操作数大小覆盖前缀。

    Group 4:地址大小覆盖前缀。

    1.2)Opcode:操作码,这是唯一不可省略的项,1、2或3个字节,在某些情况下会有额外的三个位作为补充opcode,这三个位是ModR/M中的Reg/Opcode域。

    1.3)ModR/M:一共有三个域,Mod,Reg/Opcode, R/M,具体编码格式参考Op/En列。

    Reg/Opcode在特定情况下作为Opcode的补充操作码,特定情况下作为第一个或第二个操作数寄存器。

    MOV opcode:

    image

    MOV Op/En:

    image

    对于89 /r,Op/En为MR,Reg/Opcode表示第二个操作数Operand2寄存器。

    而对于8B /r,Op/En为RM,Reg/Opcode则表示第一个操作数Operand1寄存器。

    • Mod字段与R/M字段组合形成32个可能的值:八个寄存器和24个寻址模式。

    • Reg/Opcode字段指定一个寄存器或三位操作码信息。Reg/Opcode字段的用途在主操作码中指定。

    • R/M字段可以为存器指定操作数,也可以将其与Mod字段组合形成编码寻址模式。有时,Mod字段和R/M字段的某些组合用于表示某些指令的操作码信息。

    ModR/M字节的某些编码需要第二个寻址字节(SIB字节),32位寻址的base-plus-index和scale-plus-index形式需要SIB字节。SIB字节包括以下字段:

    • "scale"字段指定比例因子。

    • "index"字段指定索引寄存器的寄存器索引

    • "base"字段指定基本寄存器的寄存器索引

    • 有关ModR/M和SIB字节的编码,请参见第2.1.5节

    1.4)SIB:定义ModR/M的寻址方式的补充寻址方式,使用"Base + Scaled Index"格式。

    1.5)Displacement:偏移,可选,0,1,2,4个字节。

    1.6)Immediate:立即数,可选,0,1,2,4个字节。

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

    image

    图在Intel手册Volume2 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相同。它有以下作用:

    • 指定GPRs和SSE寄存器

    • 指定64位操作数大小

    • 指定扩展寄存器

    image

    并非所有指令都需要64位模式下的REX前缀。 仅当一条指令引用扩展寄存器之一或使用64位操作数时,才需要前缀。 如果在没有含义的情况下使用REX前缀,则将其忽略。

    三、使用ModR/M字节的32位寻址

    image

    图在Intel手册Volume2 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位的偏移。

    <colgroup><col style="width: 32px;"><col style="width: 32px;"><col style="width: 32px;"></colgroup>
    |

    ModR/M.mod

    |

    寻址模式

    |

    描述

    |
    |

    00

    |

    [base]

    |

    提供 [base] 形式的 memory 寻址

    |
    |

    01

    |

    [base + disp8]

    |

    提供 [base + disp8] 形式的 memory 寻址

    |
    |

    10

    |

    [base + disp32]

    |

    提供 [base + disp32] 形式的 memory 寻址

    |
    |

    11

    |

    register

    |

    提供 register 寻址。

    |

    四、使用SIB字节的32位寻址

    image

          图在Intel手册Volume2 2.5.1章节Addressing-Mode Encoding of ModR/M and SIB Bytes

    SIB结构使用"Base + Scaled Index"格式。

    Base的可选值为: image

    Scaled Index的可选值为:none、[REG]、[REG2]、[REG4]、[REG*8],REG为实际的某个寄存器。

    none表示没有Scaled Index,即Scaled Index的为0。

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

    [REG2]表示使用寄存器乘以2如[EAX2]、[ECX2]和[EDX2]等等。

    五、MOVE-Move指令格式

    image

    图在Intel手册Volume2 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-7之前,例如/0或/7,表示指定有ModR/M选项,且只使用r/m,reg字段包含提供指令操作码扩展名的数字,例如/4表示reg字段为100B。

    完整解释请看Intel手册Volume2第3.1.1.1章节Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

    六、ADD-Add指令格式

    image

                  图在Intel手册Volume2 3.2章节ADD-Add小节

    七、MOVSX/MOVSXD指令格式

    image

          图在Intel手册Volume2 4.3章节MOVSX/MOVSXD—Move with Sign-Extension小节

    八、JMP—Jump指令格式****

    **** image

    ****

    解释:

    |

    代码

    |

    指令

    |

    说明

    |
    |

    EB cb

    |

    JMP rel8

    |

    相对短跳转,位移量相对于下一条指令,跳转地址为RIP + 2 + rel8

    |
    |

    E9 cw

    |

    JMP rel16

    |

    相对近跳转,位移量相对于下一条指令,跳转地址为RIP + 3 +rel16

    |
    |

    E9 cd

    |

    JMP rel32

    |

    相对近跳转,位移量相对于下一条指令,跳转地址为RIP + 5 + rel32

    |
    |

    FF /4

    |

    JMP r/m16

    |

    绝对间接近跳转,地址由 r/m16 给出

    |
    |

    FF /4

    |

    JMP r/m32

    |

    绝对间接近跳转,地址由 r/m32 给出

    |
    |

    FF /4

    |

    JMP r/m64

    |

    绝对间接近跳转,地址由 r/m64 给出,跳转地址为*(REG + r/m64),/4表示Reg/Opcode为100B

    |
    |

    EA cd

    |

    JMP ptr16:16

    |

    绝对远跳转,地址由操作数给出

    |
    |

    EA cp

    |

    JMP ptr16:32

    |

    绝对远跳转,地址由操作数给出

    |
    |

    FF /5

    |

    JMP m16:16

    |

    绝对间接远跳转,地址由 m16:16 给出

    |
    |

    FF /5

    |

    JMP m16:32

    |

    绝对间接远跳转,地址由 m16:32 给出

    |

    ****8.1)示例(x64环境)****

    *0x0000000000405f10 ff 25 32 52 20 00 jmpq 0x205232(%rip)

    属于FF /4 JMP r/m64,跳转地址为=*(rip + 0x205232),其中ModR/M=0x25=00100101B,Mod=00B,Reg/Opcode=/4=100B,R/M=101

    ******0x0000000000408f97 ff a0 17 00 00 ac jmpq *-0x53ffffe9(%rax)******

    属于FF /4 JMP r/m64,跳转地址为=*(rax + 0xac000017),其中ModR/M=0xa0=10100000B,Mod=10B,Reg/Opcode=/4=100B,R/M=000

    *0x0000000000408fbf ff a8 05 00 00 0a ljmpq 0xa000005(%rax)

    属于FF /5 JMP m16:32,跳转地址为=*(rax + 0x0a000005),其中ModR/M=0xa8=10101000B,Mod=10B,Reg/Opcode=/5=101B,R/M=000

    九、与之相关的注册码

    image image

        完整解释请看Intel手册Volume2 第3.1.1.1章节Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

    在64位模式下,使用RAX/RCX/RDX/RBX/RSP/RBP/RSI/RDI不需要REX Prefix,而使用R8 ~ R15则是必须的

    十、示例代码分析

    10.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指令格式,符合条件的只有

    image

    通过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

    10.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指令格式,符合条件的只有

    image

    通过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

    10.3)示例三(x86环境)

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

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

    [esi+ecx*4]是一个内存地址,eax为32位寄存器,所以指令应该是"ADD m32,r32",根据第五节 ADD-Add指令格式,符合条件的只有

    image

    通过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结构

    image

    所以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

      10.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指令格式,符合条件的只有

    image

    通过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。

    image

    最后的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)英特尔指令参考手册:https://www.felixcloutier.com/x86/

    7)英特尔64与IA-32体系结构软件开发人员手册: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

    8)英特尔64与IA-32体系结构优化参考手册:https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf

    手头不方便的时候,看到自己喜欢的东西无妨采取 “ 过我眼者即为我有 ” 得之我幸,失之我命 ” 心态。

    指令的第一字节决定了指令的类型,并且,也是由第一字节决定了,是否还要继续取第2或第3字节。
    指令的翻译主要是针对第1字节(51的指令只有256条),后面1或2字节是数据或地址。可以根据第1字节的类型,相应处理第2或第3字节。

    指令译码一般有几个过程(部件):指令预取、指令预分析(预解码)、解码。预取是从cache或者内存取一系列的字节(大小可以保证至少包含一条指令),并设置一个待分析的位置,预分析从此位置逐字节分析,如果是前缀就设置分析状态(因为前缀可能改变默认地址尺寸和操作数的大小,影响后续指令长度),直到不是前缀,就认为是操作码,x86的op code长度一般为1字节,某些2字节,查表就可以直接找出指令长度了。

    radare2 最近越来越流行,已经进入 github 前 25了,看到大佬们纷纷推荐,为了紧跟时代潮流,我也决定探究探究这款 神器 。下面画画重点,以便以后需要用了,可以方便查找。

    https://github.com/radareorg/radare2

    image.png
    image.png
    image.png
    image.png
    image.png

    相关文章

      网友评论

          本文标题:指令集编码与解析

          本文链接:https://www.haomeiwen.com/subject/xqevmktx.html