我知道有一些库可以“解析”二进制机器码/操作码以确定x86-64 CPU指令的长度。
但是我想知道,既然CPU本身有内部电路来确定这一点,是否有一种方法可以使用处理器本身从二进制代码中获取指令大小?(甚至可能是一个黑客技巧?)
但是我想知道,既然CPU本身有内部电路来确定这一点,是否有一种方法可以使用处理器本身从二进制代码中获取指令大小?(甚至可能是一个黑客技巧?)
ptrace
,因此您可以创建一个非特权沙箱进程,在其中可以遍历一些未知的机器码字节...)破解x86 ISA by Christopher Domas 对这种技术进行了更详细的讲解,包括使用它来查找未记录的非法指令,例如9a13065b8000d7
是一个7字节的非法指令; 这时它就停止了页面错误。 (objdump -d
只会显示 0x9a (bad)
并解码其余的字节,但显然实际的英特尔硬件不满足于它是坏的,直到它获取了另外6个字节)。
instructions_retired.any
也暴露了指令计数,但是如果不知道指令的结束位置,你就不知道在哪里放置rdpmc
指令。使用0x90
NOP进行填充并查看执行的总指令数可能不起作用,因为你必须知道在哪里切断和开始填充。
与CPU花费的时间相比,反汇编机器代码所花费的时间非常少,而CPU花费的时间则主要用于浮点数运算或图像处理等特殊用途。我们有SIMD FMA和AVX2 vpsadbw
之类的东西来加速CPU花费大量时间进行的这些特殊用途,但对于我们可以轻松通过软件完成的事情,没有必要添加这样的东西。
记住,指令集的目的是使创建高性能代码成为可能,而不是变得过于元和专注于解码本身。
在专用的复杂性上端,SSE4.2字符串指令在Nehalem中被引入。它们可以做一些很酷的东西,但很难使用。https://www.strchr.com/strcmp_and_strlen_using_sse_4.2(还包括strstr,这是一个真正的应用案例,其中pcmpistri
可以比SSE2或AVX2更快,不同于strlen / strcmp,其中普通的pcmpeqb
/ pminub
如果使用有效(请参见glibc的手写汇编)效果非常好。)总之,即使在Skylake中,这些新指令仍然是多uop的,并且并没有被广泛使用。我认为编译器很难自动向量化,大多数字符串处理是用语言完成的,在这些语言中,很难将几个具有低开销的内部函数紧密地集成在一起。
VectoredHandler
中再次设置TRACE_FLAG
,如果要继续跟踪,则返回EXCEPTION_CONTINUE_EXECUTION
,如果不设置标志并返回EXCEPTION_CONTINUE_SEARCH
,则表示我们想要停止自身跟踪(异常已由SEH处理)。 - RbMm