环境:

  win7_x64旗舰版、VS2015企业版

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

  

                图在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。

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

    

    对于89 /r,Reg/Opcode表示第二个操作数寄存器,而对于8B /r,Reg/Opcode则表示第一个操作数寄存器。

  • 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)

  

              图在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位操作数大小
  • 指定扩展寄存器

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

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

      图在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位的偏移。

ModR/M.mod

寻址模式

描述

00

[base]

提供 [base] 形式的 memory 寻址

01

[base + disp8]

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

10

[base + disp32]

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

11

register

提供 register 寻址。

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

  

      图在Intel手册Volume2 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]等等。

五、MOVE-Move指令格式

  

                图在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:表示指定有ModR/M选项。

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

六、ADD-Add指令格式

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

七、MOVSX/MOVSXD指令格式

  

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

八、与之相关的注册码

  

  

    完整解释请看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则是必须的

九、示例代码分析

  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)英特尔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

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

Intel汇编指令格式解析的更多相关文章

  1. x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式

    目录 x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式 一丶x86指令复习. 1.1什么是x86指令. 1.2 x86与x64下的通用寄存器 1.3 OpCode 1.4 7种寻址方式 二 ...

  2. AT&T 和 Intel 汇编语法的主要区别

    转自AT&T 和 Intel 汇编语法的主要区别 作为一个爱折腾的大好青年,补番之余还要补一些 Linux 下的基础,比如 GDB 的正确使用方法.但无论是看 gdb 还是 gcc -S 里的 ...

  3. 《Intel汇编第5版》 Intel CPU小端序

    一.MASM汇编器中的数据类型 二.Intel汇编中的立即数类型 三.定义有符号和无符号整数 四.小端序 内存中数据按照字节存储,一个4个字节无符号整数,其高位存储在低地址上,低位存储在高地址上. 比 ...

  4. Motorola和Intel格式报文解析的区别

      结论:无论用的Motorola,还是Intel格式,只在单个信号跨字节时解析才有区别. 先看下Vector的CANoe中dbc编辑器是如何呈现报文的: 图1 CAN报文中byte与bit顺序 从图 ...

  5. ATT汇编与Intel汇编的区别,摘自《深入分析linux内核源码》一书

    2.6.1 AT&T与Intel汇编语言的比较 我们知道,Linux是Unix家族的一员,尽管Linux的历史不长,但与其相关的很多事情都发源于Unix.就Linux所使用的386汇编语言而言 ...

  6. Linux下AT&T汇编语法格式与Intel汇编语法格式异同

    由于绝大多数的国内程序员以前只接触过Intel格式的汇编语言,很少或几乎没有接触过AT&T汇编语言,虽然这些汇编代码都是Intel风格的.但在Unix和Linux系统中,更多采用的还是AT&a ...

  7. Intel HEX文件解析

    近期有一个需求就是为Arduino开发板做一个基于蓝牙的无线烧录程序.眼下的Arduino程序都是通过USB线连接到电脑的主机上,实际的传输过程是基于USB协议的,这个过程还是比較麻烦的.由于每次的编 ...

  8. 002_linux之点灯(汇编深度解析)

    1.      开发板采用韦山东的开发板 2.      芯片CPU三星S3C2440A 3.  控制引脚:GPF4 4.  linux操作系统 5. 芯片手册下载地址:https://eyun.ba ...

  9. Intel汇编程序设计-整数算术指令(中)

    7.3  移位和循环移位的应用 7.3.1  多双字移位 要对扩展精度整数(长整数)进行移位操作,可把它划分为字节数组.字数组或双字数组,然后再对该数组进行移位操作.在内存中存储数字时通常采用的方式是 ...

随机推荐

  1. union 和struct大小计算

    一.字节对齐 现代计算机的内存空间是按照字节(byte)来划分的,字节对齐的意思是在给特定变量类型分配内存空间的时候,变量的内存地址是它本身变量类型大小的整数倍.比如,给int类型的变量a分配地址空间 ...

  2. oracle入门之分页查询

    oracle的分页查询共三种方法 1.根据ROWID来分页(速率一般) SQL>select * from emp where rowid in (select rid from (select ...

  3. Sql Server 2012 集群配置

    基于Windows Server 2008 R2的WSFC实现SQL Server 2012高可用性组(AlwaysOn Group) 2012年5月 微软新一代数据库产品SQL Server 201 ...

  4. 斐讯K2 22.5.9固件刷华硕固件实测教程

    斐讯K2最新的固件是V22.5.9.163这个版本是锁死了,不能刷机的,而且不能降级到原来的可以刷机的老版本固件,也就不能刷第三方固件了,怎么破呢?下面就教大家怎么降级刷机到V22.4.2.8固件.  ...

  5. 性能测试LR学习笔录 -2

    LoadRunner基本测试流程: 制定性能测试计划(部分)  -> 创建测试脚本 -> 编译.运行测试脚本 -> 创建场景 - > 运行.监控场景.收集数据  -> 生 ...

  6. ubuntu 18.04启动samba图形管理界面

    启动samba图形界面管理器出现错误: Failed to load module "canberra-gtk-module" 或 SystemError: could not o ...

  7. js循环出相同name,不同id的按钮,对其进行点击回复操作

    function getseat(){ var option= "<button class='btn'style='margin:5px;' onclick='onclickSeat ...

  8. MySQL80修改密码

    mysql> update user set password=password('123') where user='root' and host='localhost'; ERROR 106 ...

  9. 西部数码虚拟空间配置ssl

    1.在阿里云申请ssl证书 2.解析到西部数码cname地址 3.西部数码---> 申请ssl部署 4.申请托管证书 5.部署https后设置301跳转将http跳转到https  参照: ht ...

  10. Knowledge From Practice(rf,fiddler)

     1.较精准定位 2.关于Appium+RF的轴表达式 child:选取当前节点的所有子元素 parent:选取当前节点的直接父元素 descendant:选取当前节点的所有后代元素 ancestor ...