如何使gcc为-fpatchable函数项发出多字节NOP?

如何使gcc为-fpatchable函数项发出多字节NOP?,gcc,assembly,x86,x86-64,Gcc,Assembly,X86,X86 64,gcc确实能够使用多字节NOP来对齐循环和函数。然而,当我尝试这个方法时,它总是发出单字节NOP 您可以看到,gcc将函数与nop DWORD PTR[rax+rax*1+0x0]和nop WORD PTR cs:[rax+rax*1+0x0]对齐,但当我指定-fpatchable function entry=8,3 我在文件中看到了这一点 -fpatchable function entry=N[,M] 在每个函数的开头生成N个NOP,函数入口点在第m个NOP之前。如果省略M,则默认为0,

gcc确实能够使用多字节NOP来对齐循环和函数。然而,当我尝试这个方法时,它总是发出单字节NOP

您可以看到,gcc将函数与
nop DWORD PTR[rax+rax*1+0x0]
nop WORD PTR cs:[rax+rax*1+0x0]
对齐,但当我指定
-fpatchable function entry=8,3

我在文件中看到了这一点

-fpatchable function entry=N[,M]

  • 在每个函数的开头生成N个NOP,函数入口点在第m个NOP之前。如果省略M,则默认为0,因此函数入口仅指向第一个NOP处的地址。如果代码段是可写的,NOP指令将保留额外的空间,可用于在运行时修补任何所需的检测。通过NOP的数量间接控制空间量;使用的NOP指令对应于内部GCC后端接口发出的指令
    gen_NOP
    。此行为是特定于目标的,也可能取决于体系结构变量和/或其他编译选项
它明确表示将插入N个NOP。然而,我认为这应该是一个N字节的NOP(或者填充N字节空间的最优NOP数)。类似地,如果指定了M,则需要发出M字节和(N− M) -字节NOP


那么gcc为什么要这样做呢?我们能让它生成多字节NOP吗?两个0x90 NOP是否比Microsoft的
mov edi、edi

好?多字节NOP可能是由汇编程序通过其对齐指令生成的。请注意,严格地说,该选项按照文档和预期工作,参数是插入的NOP指令数,而不是NOP指令的字节数。更改此行为使其按您认为的方式工作将是不兼容的更改,并且可能会破坏使用此选项的现有应用程序。您可能需要查看
ms\u hook\u prologue
函数属性,看看它是否符合您的要求,否则我认为您需要自己实现它;每个都在uop缓存中获取一个条目,以及前端问题带宽的单独插槽。与大型函数开始时的
推送
和其他简短指令一起,在一个函数的前32字节机器代码中可能会有太多的UOP,无法在Sandybridge-family上容纳3行最多6个UOP。似乎当前的最佳选择是。此外,从这个角度来看,这似乎是一个“懒惰”的设计选择。