X86 指令格式及编码解析 (IA32 Mode)

本文详细介绍了IA32 Mode下的X86指令格式,包括前缀字节、操作码、ModR/M、SIB、偏移量和立即数等组成部分。通过解析Mod、R/M、REG/OPCODE、Scale、Index和Base等字段,深入理解X86指令的寻址方式和编码规则。

IA32-Mode SMD指令格式

 

X86指令由:

  • 前缀字节prefix (非必需)
  • 操作码opcode (必须)
  • 内存/寄存器操作数字节ModR/M (非必需)
  • 索引寻址描述字节SIB (非必需)
  • 常数偏移字节/半字/字Displacement (非必需)
  • 立即数字节/半字/字 Immediate (非必需)

 

  1. prefix解析

种类

名称

二进制码

说明

LOCK

LOCK

F0H

为了让指令在执行时候先禁用数据线的复用这个特性用在多核的处理器上一般很少需要手动指定

REP

REPNE/REPNZ

F2H

用CX(16位下)或ECX(32位下)或RCX(64位下)作为指令是否重复执行的依据

REP/REPE/REPZ

F3H

同上

Segment Override

CS

2EH

段重载(默认数据移动指令使用DS段)

SS

36H

同上

DS

3EH

同上

ES

26H

同上

FS

64H

同上

GS

65H

同上

Oprandsize

Override

Oprandsize

Override

66H

访问32位和16位寄存器用这个前缀来区别

Address

Override

Address

Override

67H

64位下指定用64位还是32位寄存器作为索引

 2. ModR/M 解析

 

   由上面的指令格式已知Mod/RM域分为3个部分:

  • Mod (两个位)
  • Reg/Opcode (三个位)
  • R/M (三个位)

 

  2.1 Mod

以上左图是16位下的modr/m解析,右图是32位下modr/m解析

Mod由两个位组成,来指定寻址方式,分别是

 

2.2 R/M

  1. 寄存器寻址
  2. 寄存器加偏移寻址(8位)
  3. 寄存器加偏移寻址(16/32位)
  4. 寄存器操作数(只操作寄存器而非内存)

Mod是两位的数据所以可以指定4种寻址方式,而每一种方式里面还对应着不同的选择,这些不同的选择由R/M来决定,这个域由3个位组成,也就是说有8种方式来选择,由上面的图可以对应从000B到111B的所有编码对应的选择.

 

2.3 REG/OPCODE

这个域由不同的opcode来决定功能到底是opcode的补充还是作为oprand的编码.

 

16/32位的编码如下

 

3. SIB解析

在modr/m解析中红色圈出来的和其他不同,原因是当mod≠11(也就是访问内存操作而不是寄存器操作)的时候,当R/M=100B的时候,说明要使用”索引寻址”,这个时候,指令的编码就会使用SIB字节,这个字节由3部分组成,分别是Scale Index Base.

 

举例来说,一条mov指令如下:

       mov ptr [ebx + eax * 4], ecx

这条mov把ecx寄存器中的内容mov到 ebx + eax * 4 的内存地址中,这样的地址,就是索引寻址,也就是说会使用SIB字节,而其中

  1. ebx 是 Base
  2. eax 是 Index
  3. scale值是4

 

 

 

 

 

 

 

这张表是32位下SIB的编码方式 (16位模式不支持这种寻址方式)

 

3.1 Scale

类似于Mod,两个位组成,来选择index到底要乘以几来组成最后的寻址地址,可选项是1 2 4 8,四种选择.

3.2 Index

类似于R/M来指定到底是那个寄存器一样,index这个域来指定到底是用哪个寄存器作为index

3.3 Base


来指定基地址,需要注意的是在汇编中,这个base可以省略,那么实际上在指令的编码中一定有对应项说明base是被省略的---就是base=101B的时候.

25     asm(

26         "movw %%ax, %%bx; \

27          movb %%bh, %%ch; \

28          movl (%%eax, %%eax, 4), %%ebx;  \

29          movq (%%rax, %%rbx, 4), %%rbx; \

30          movl (, %%eax, 4), %%ebx; \

31          movq (, %%rax, 4), %%rbx"

32     : \

33     : \

34     );

上面的这部分嵌入式汇编代码,编译生成二进制之后我再反汇编出结果对比如下:

 

  400689:       66 89 c3                mov    %ax,%bx

  40068c:       88 fd                   mov    %bh,%ch

  40068e:       67 8b 1c 80             mov    (%eax,%eax,4),%ebx

  400692:       48 8b 1c 98             mov    (%rax,%rbx,4),%rbx

  400696:       67 8b 1c 85 00 00 00     mov    0x0(,%eax,4),%ebx

 

两条代码的比对,可发现上面的规则,也就是没有指定base的时候会引入一个立即数作为偏移,但是如果指令没有指定立即数则汇编器就把立即数写成0.

 

4. Displacement

偏移数,1 2 或 4 个字节, 按照小端排列.

例: 48 8b 1c 85 cd ab 00    mov    0xabcd(,%rax,4),%rbx

 

5. Immediate

立即数,1 2 或 4 个字节, 按照小端排列

 

举例说明:

 

 

以上就是IA32 Mode下指令的编码,64Bit Mode的编码文章链接https://blog.youkuaiyun.com/ross1206/article/details/81663614

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值