【发布时间】:2019-02-26 12:57:33
【问题描述】:
我目前正在为 x86_x64 CISC 开发反汇编程序。 我有两个关于前缀指令解码的问题:
-
对于以下流:
\x9b\x9b\xd9\x30GCC和objdump输出fstenv [eax]所以他们首先读取所有前缀 (不超过15个)然后继续检查正确的指令 使用最后一个前缀读取
\x9b和\xd9使其成为fstenv说明。Capstone另一方面输出wait wait fnstenv dword ptr [eax]现在,显然是错误的 它放了 2 个
wait指令,而不仅仅是 1 个。但它应该放wait说明全部或GCC和objdump在右侧 在这里消耗所有额外的\x9b前缀fstenv指令? -
对于以下流:
\xf2\x66\x0f\x12\x00GCC和objdump输出data16 movddup xmm0,QWORD PTR [eax]所以他们正在安排 以特定顺序添加前缀,因此
\x66在\xf2之前解释 因此,他们仍然使用最后一个前缀\xf2来 确定指令movddup。所以他们在这里是为了 使用前缀的这种排列逻辑还是错误?Capstone另一方面输出movlpd xmm0, qword ptr [eax]所以他们没有按任何顺序排列前缀,他们只是 取最后一个前缀
\x66来确定指令movlpd在这种情况下看起来比GCC和objdump正在做。
cpu实际上是如何解释这些流的?
【问题讨论】:
-
1)
fstenv并不存在。指令集参考说:“汇编器为 FSTENV 指令发出两条指令(一条 FWAIT 指令后跟一条 FNSTENV 指令),处理器分别执行这些指令中的每一条。” Capstone 在技术上是正确的。 -
前缀有强制顺序。忘记是哪一个了,你可以看看说明书。如果前缀顺序错误,则行为未定义。
-
指令集参考说:“指令前缀 [...] 可以按相对于彼此的任何顺序放置。” 请注意,
wait不是前缀. -
2) 将
F2前缀应用于该指令是未定义的,因此很难争论哪个版本是正确的。我的 cpu (amd ryzen 1700) 似乎认为 objdump 是对的,它被执行为movddup。 TBH,我希望它是movlpd... -
@Jester This answer 声称对于 SSE 指令,如果两个组都出现,则 F2/F3 击败 66。
标签: assembly x86 x86-64 disassembly