处理包含来自同一组的多个前缀的 x86/64 指令的正确方法是什么?

逆向工程 拆卸 x86 x64
2021-07-09 07:09:37

具体来说,如果来自同一组的多个前缀,Olly 只会接受它找到的最后一个前缀。例如

lock rep add dword ptr[eax],eax    ; f0 f3 01 00

变成

???                           ; f0                 
rep add dword ptr[eax],eax    ; f3 01 00

英特尔架构手册的第 28 页简单地指出“最多只包含来自四组中的每一组的一个前缀代码是有用的......”但它没有说每组最多只有一个. 是的,在某些情况下,某些前缀是必需的,不能存在,或者仅根据说明有效,但我不是指任何这些情况。

我选择将英特尔的指南解释为“它是有效的,但没有太多理由这样做”,并且我将继续保留指令中列出的前缀(同样,除非任何特定规则另有说明。)

这是处理这种情况的正确方法还是我应该做一些不同的事情?

1个回答

一般的经验法则是按顺序应用每个前缀。例如,两个66前缀相互抵消,与66 66 66single 相同66

编辑:看来我错了,重复的前缀被忽略。

SSE 指令的情况变得有些混乱,其中一些前缀是强制性的,一些是可选的,并且它们的顺序可能很重要。例如,如果 F2 和 F3 都与 SSE 指令一起使用,则最后一个“获胜”,如果存在其他前缀,则忽略 66(CRC32 等少数指令除外)。

66 f3 f2 0f 59 ff     ; mulsd xmm7, xmm7
66 f2 f3 0f 59 ff     ; mulss xmm7, xmm7
66 0f 59 ff           ; mulpd xmm7, xmm7
f2 66 0f 59 ff        ; mulsd xmm7, xmm7

一般来说,文档并没有很好地描述极端情况。所以最好的办法是将一些字节放入一个文件中,在实际的 CPU 上运行它,然后观察会发生什么。