x86指令编码(硬编码)的结构

image-20240725230021629

  1. opcode最少1个字节,最多3个字节。
  2. opcode是指令中最重要的组成部分。
  3. 前缀指令只能影响自己,而opcode、ModR/M、SIB决定了整条指令的长度。
  4. 有没有ModR/M是由opcode决定的,有没有SIB是由ModR/M决定的。

定长指令、变长指令

  • 定长指令(精简指令集 arm):它的长度永远没有变化,只要opcode的长度确定了,那么它的长度就确定了。
  • 变长指令(复杂指令集 intel amd):仅仅通过opcode是没有办法确定长度的。

如何区分指令定长还是变长?

opcode后面没有ModR/M,该指令就是定长指令。如果opcode后面紧跟ModR/M,该指令就是变长指令

1
2
3
4
5
6
7
操作码(1字节)   寻址方式   操作数
操作码(1字节) 2bit(寻址方式) 3bit(源操作数) 3bit(目的操作数)
寻址方式:
11 => 寄存器=>寄存器
10 => [bx+di+xxx]
01 => [bx+di-xxx]
00 => [bx+di]

寄存器寻址方式

  • 操作数存放在CPU的内部寄存器reg中,可以是:
    • 8位寄存器r8:AH、AL、BH、BL、CH、CL、DH、DL
    • 16位寄存器r16:AX、BX、CX、DX、SI、DI、BP、SP
    • 4个段寄存器seg:CS、DS、SS、ES

立即数寻址方式

  • 指令中的操作直接存放在机器代码中,紧跟在操作码之后(操作数作为指令的一部分存放在操作码之后的主存单元中)
  • 这种操作数被称为立即数imm
    • 它可以是8位数值i8(00H~FFH)
    • 也可以是16位数值i16(0000H~FFFFH)
  • 立即数寻址方式常用来给寄存器赋值

寄存器间接寻址方式

  • 有效地址存放在基址寄存器BX或变址寄存器DI中
  • 默认的段地址在DS段寄存器,可使用段超越前缀改变

image-20240726215700587

直接寻址方式

  • 有效地址在指令中直接给出
  • 默认的段地址在DS段寄存器,可使用段超越前缀改变

image-20240726215454529

寄存器相对寻址方式

  • 有效地址是寄存器内容与有符号8位或16位位移量之和,寄存器可以是BX、BP或SI、DI

    1
    有效地址=BX/BP/SI/DI+8/16位位移量
  • 段地址对应BX/SI/DI寄存器默认是DS,对应BP寄存器默认是SS;可用段超越前缀改变

image-20240726212000645

基址变址寻址方式

  • 有效地址由基址寄存器(BX或BP)的内容加上变址寄存器(SI或DI)的内容构成:

    1
    有效地址=BX/BP+SI/DI
  • 段地址对应BX基址寄存器默认是DS,对应BP基址寄存器默认是SS;可用段超越前缀改变

image-20240726214752213

image-20240726214936906