x64指令格式

人走茶凉 提交于 2019-12-01 00:28:09

引言

看了两天的x86指令集,终于基本搞懂了x64的指令格式(只是x64哦,没有特别关注16位和32位时的格式),和RISC相比实在是太复杂了,难怪x86的功耗将不下来,光是译码器就不知道得做的多么复杂。

x64指令格式

x64指令共包括七个部分,即:

  • legacy prefix(一个字节)
  • REX prefix(一个字节)
  • opcode(一到三个字节)
  • ModRM(一个字节)
  • SIB(一个字节)
  • disp(最多可以8个字节)
  • imm(最多可以8个字节)

legacy prefix

legacy prefix在x64下应该不常用。一种情况是需要使用16位的operand时(例如mov ax 0x1234),需加前缀0x66以改变default operand size(x64下该值是32)。还有就是需要lock的情况。还有其他情况就没有细看了。

REX

REX前缀非常重要,正是这个前缀将x86带入了64位模式。它的高四位一定是0x4,低四位分别代表W、R、X、B。

  • W:x64模式下大部分指令的default operand size是32位的,对这类指令,如果需要64位的操作数,将需要将W置位,例如mov rax rbx
  • R:将ModRM.reg从8个扩展到16个。
  • X:将SIB.index寄存器从8个扩展到16个
  • B:将SIB.base或者ModRM.r/m或者Opcode.reg寄存器从8个扩展到16个。所以能有如上的关系,是因为当SIB.base表示base寄存器时,ModRM.r/m必为100以作为SIB域的存在标记,而不再表示一个寄存器。

Opcode

Opcode的长度可以从一个字节到三个字节不等。一个字节时有时需要配合ModRM.reg才能明确具体功能。我们在指令手册中看到opcode /d的情况这个/d就是指的ModRM.reg的值。另外opcode两个字节时第一个字节一定是0x0F作为引导。

ModRM

ModeRM字段又2-3-3的依次分成moderegr/m三个域。

reg域通常作为指令的dest寄存器,或者作为某些opcode的补充。

mode=11时表示寄存器直接寻址,寄存器由r/m域指定,例如r/m=000就表示直接取rax寄存器的值。

mode=00表示寄存器间接寻址,寄存器由r/m域指定,即[r/m],但有两种特殊情况:

  • r/m=100不表示[rsp],而是作为SIB字段的存在标志
  • r/m=101不表示[rbp],而是表示仅包含立即数的间接寻址,即[disp32]

mode=01通常表示[r/m+disp8],但

  • 如果r/m=100,则表示[base+index*scalar+disp8]
  • 如果r/m=101,则表示[rbp+disp8]

mode=10表示[r/m+disp32]

  • 如果r/m=100,则表示[base+index*scalar+disp32]
  • 如果r/m=101,则表示[rbp+disp32]

最后,针对rsp,如果的确需要[rsp],补救的措施是当r/m=100时,将SIB的index域也置为100,并令此时表示[base],这样令base=100,就表示[rsp]了。总结一下:

  • mode=00, r/m=100, index=100, base=100 表示[rsp]
  • mode=01, r/m=100, index=100, base=100 表示[rsp+disp8]
  • mode=10, r/m=100, index=100, base=100 表示[rsp+disp32]

最最后,x64不支持[rbp],如果非要[rbp],只能用[rbp+0x00]编码

SIB

SIB字段2-3-3的依次分为scalar、index和base三个域。

scalar取00表示乘1, 取01表示乘2, 取10表示乘4, 取11表示乘8.

index用于指示8个寄存器,结合REX.X位指示16个寄存器。

base用于指示8个寄存器,结合REX.B位指示16个寄存器。

如何参考Intel指令手册

字(word)是16位,32位称为双字,64位称为四字。

Intel格式汇编如果有两个操作数,通常dest在左,src在右,如mov dest src

REX.W:指示operand size的变化

/digit:指示ModRM中与opcode结合以确定实际操作的reg域的值

/r:指示ModRM字段中的reg域表示dest寄存器

cb, cw, cd, cp, co, ct:A 1-byte (cb), 2-byte (cw), 4-byte (cd), 6-byte (cp), 8-byte (co) or 10-byte (ct) value following the opcode.

ib, iw, id, io:A 1-byte (ib), 2-byte (iw), 4-byte (id) or 8-byte (io) immediate operand to the instruction that follows the opcode, ModR/M bytes or SIB bytes.

+rb, +rw, +rd, +ro:没看懂!!

r/m32: A doubleword general-purpose register or memory operand used for instructions whose operand-size attribute is 32 bits.

r/m64:A quadword general-purpose register or memory operand used for instructions whose operand-size attribute is 64 bits when using REX.W.

参考文献

  1. Intel® 64 and IA-32 Architectures Software Developer’s Manual,Volume 2A:Instruction Set Reference, A-M
  2. http://www.mouseos.com/x64/index.html

原文:大专栏  x64指令格式


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!