我正在撤销一些应用程序,我遇到了这个操作码:
PSHUFB XMM2, XMMWORD_ADDRESS
我尝试在python中实现此函数的算法但没有成功! 这个操作码应该如何工作的参考是: http://www.felixcloutier.com/x86/PSHUFB.html
以下是代码段:
PSHUFB (with 128 bit operands)
for i = 0 to 15 {
if (SRC[(i * 8)+7] = 1 ) then
DEST[(i*8)+7..(i*8)+0] ← 0;
else
index[3..0] ← SRC[(i*8)+3 .. (i*8)+0]; DEST[(i*8)+7..(i*8)+0] ← DEST[(index*8+7)..(index*8+0)];
endif
}
DEST[VLMAX-1:128] ← 0
我试图实现此操作码的128版本但没有成功。 以下是函数
之前和之后的值之前
WINDBG>r xmm2
xmm2= 0 3.78351e-044 6.09194e+027 6.09194e+027
后
WINDBG>r xmm2
xmm2=9.68577e-042 0 4.92279e-029 4.92279e-029
在python中你可以使用'struct'将那些从float数字改为Hex:
hex(struct.unpack('<I', struct.pack('<f', f))[0])
所以我可以说这些是 PSHUFB 操作码之前和之后 XMM2 的十六进制值:
之前
xmm2 = 0 0x0000001b 0x6d9d7914 0x6d9d7914
后
xmm2 = 00001b00 00000000 10799d78 10799d78
最重要的是,我差点忘了.. XMMWORD_ADDRESS 的价值是:
03 02 01 00 07 06 05 04 0D 0C 0B 0A 09 08 80 80
xmmword 808008090A0B0C0D0405060700010203h
可以高度赞赏Python中的实现。 C中的实现也可以起作用
或者可能解释它是如何运作的! 因为我无法理解英特尔的参考资料
这是我到目前为止的代码算法
x = ['00', '00', '00', '00', '00', '00', '00', '1b', '6d', '9d', '79', '14', '6d', '9d', '79', '14']
s = ['03', '02', '01', '00', '07', '06', '05', '04', '0D', '0C', '0B', '0A', '09', '08', '80', '80']
new = []
for i in range(16):
if 0x80 == int(s[i], 16) & 0x80:
print "MSB", s[i]
new.append(0)
else:
print "NOT MSB", s[i]
new.append( x[int(s[i], 16) & 15] )
print x
print new
其中x是xmm0,s是SRC。
我得到的输出是:
['00','00','00','00','00','00','00','1b','6d','9d','79', '14','6d','9d','79','14']
['00','00','00','00','1b','00','00','00','9d','6d','14', '79','9d','6d','00','00']
我应该去哪里
['00','00','1b','00','00','00','00','00','10','79','9d', '78','10','79','9d','78']
我现在注意到的其他东西,在'output'中我得到十六进制数0x78 它可能来自哪里?
答案 0 :(得分:2)
它的工作方式类似于16个并行表查找,对具有最高位设置的索引进行特殊处理。例如,它看起来像这样:(未经过测试,而不是Python)
for (int i = 0; i < 16; i++)
new_dest[i] = (src[i] & 0x80) ? 0 : dest[src[i] & 15];
dest = new_dest;
new_dest
有重大意义,因为它实际上是16个并行分配,即先读后读,第二次查找不会受到发生的事情的影响第一个字节,依此类推。英特尔的代码片段会隐含(或者错误,取决于您如何看待它)。