-1

我需要给出 1 字节指令长度到 13 字节指令的汇编命令列表:

  • 1 字节:推,...
  • 2 字节:添加 al, ...
  • 3 字节:添加 ax, ...
  • .
  • .
  • .
  • 13 字节...

我在哪里可以找到这样的清单?
我可以看到汇编命令和指令长度(以字节为单位)。

4

2 回答 2

2

在 IDK 中,您可以找到按长度排序的列表,因为大多数指令采用 ModRM 字节,该字节可以编码可变长度寻址模式。

您可以按最小长度排序。英特尔的第 2 卷手册显示了编码,例如https://www.felixcloutier.com/x86/index.html处的 HTML 提取。

http://ref.x86asm.net/coder64.html按 1 字节和 2 字节操作码分组,并显示(在o列中)该操作码是否采用 ModRM 字节来指示操作数。

https://codegolf.stackexchange.com/questions/132981/tips-for-golfing-in-x86-x64-machine-code有一堆关于 x86-64 机器代码中小东西的提示。


顺便说一句,你的一个例子被打破了:

add ax, imm8在 64 位或 32 位模式下需要 16 位操作数大小的操作数大小前缀。编码至少需要 4 个字节。(66h+操作码+ modrm + imm8)。

add ax, imm16可以对隐式 AX 使用 no-modrm 短格式操作码,但需要一个额外的字节用于立即数。

或者你的意思是add r16, r/m16,像add ax, cx?是的,这是 3 个字节。但add ax, [1234 + edi + r8d*4]还有更多:地址大小前缀(因为我没有使用 64 位寄存器)、SIB、disp32 和 r8 的 REX 前缀。因此,您不能将所有 add ax, ...指令分组为相同的大小。即使排除了内存源操作数,也add ax, r8w需要一个 REX 前缀。

但是,是的add al, imm8,或寄存器有 2 字节编码:8 位操作数大小有自己的操作码,而不是 16/32/64 位操作码前面的前缀。

是的push/ poprax..rdi 的注册是一个字节。 r8..r15 需要一个 REX 前缀。


我忘记了没有一堆前缀的最长指令是什么。例如lock add [fs:disp32 + r10], imm32相当大。

或者一些 SIMD 指令有很多强制前缀,并且可以使用内存源操作数,因此可以有很大的寻址模式。

于 2019-12-30T14:21:38.380 回答
1

您可以在此处找到 Intel CPU 的手册:https ://software.intel.com/en-us/articles/intel-sdm

Intel-x86-64b-32b-manul-vol-2-instruction-set-reference-manual.pdf可以在上面的链接中找到对指令编码的完整参考,您可以在其中下载。

然而,没有简单的指令长度映射,因为指令是经过编码的,它们的长度取决于操作码和涉及的寻址模式以及其他参数。

根据您的用例,您可能会考虑使用类似 capstone: http://www.capstone-engine.org/的东西,您可以使用它来反汇编二进制数据,并为您提供有关指令的信息。

于 2019-12-30T21:16:04.680 回答