【发布时间】:2017-09-14 23:42:27
【问题描述】:
我正在创建一个 x86 解码器,我正在努力理解和寻找一种有效的方法来计算指令的助记符。
我知道操作码 6 MSB 是操作码位,但我在助记符表中找不到使用这 6 位的任何地方。我找到的唯一助记表是整个操作码字节本身,而不仅仅是 6 个 MSB。
我想问有哪些有效的方法可以继续解码操作码字节中编码的助记符,以及是否有使用 6 个 MSB 而不是整个操作码字节的表引用。
【问题讨论】:
-
低 2 位也是操作码的一部分...例如,
jcc指令对于从 0x70 到 0x7F 的每个操作码值都有不同的助记符。事实上,有时 ModR/M 字节中的/r字段也是操作码的一部分。 (例如shl与shr)。 -
现代 x86 机器码的问题在于没有一种有效/简单的解码方法。例如,
rep nop实际上解码为pause,或者rep bsf解码为tzcnt(如果支持BMI1,否则解码为bsf)。所以你必须检查其他指令的强制性前缀。 -
@PeterCordes 我使用的资源之一是c-jump.com/CIS77/CPU/x86/X77_0050_add_opcode.htm 我知道操作码字节的唯一 6 个 MSB 何时不代表助记符但对于常规指令似乎是这样的根据他们所说的方式。我在问这些常规情况下,我如何使用这 6 个 MSB 来确定助记符,就像他们在示例中所做的那样。
-
你的意思是像 C 语言中的
const char *mnemonic = table[(uint8_t)opcode>>2];?你就那样做。尽管实际上您可能需要structs 的 256 项表,其中一个成员是enum,说明它是什么类型的指令(或指向将解码其余字节的函数的函数指针) . -
@PeterCordes 是的,但是当在线查看助记符表时,我找不到确定真正使用哪个助记符的方法。例如,当
opcode为 0x6(推送)时,使用const char *mnemonic = table[(uint8_t)opcode>>2];查看此表sparksandflames.com/files/x86InstructionChart.html,如果我要 rsh 2 个字节,它很容易被误认为是 0x5(添加)
标签: data-structures x86 disassembly opcode mnemonics