如何让 gcc 为 -fpatchable-function-entry 发出多字节 NOP?

phu*_*clv 5 x86 assembly gcc x86-64

gcc 确实能够使用多字节NOP 来对齐循环和函数。但是,当我尝试该-fpatchable-function-entry选项时,它总是发出单字节NOP

您可以在此示例中看到 gcc 将函数与函数对齐nop DWORD PTR [rax+rax*1+0x0]nop WORD PTR cs:[rax+rax*1+0x0]但是当我指定时,在函数入口处使用了八个 0x90 NOP-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(或任何最佳数量的 NOP 来填充 N 字节空间)。同样,如果指定了 M,则需要发出一个M 字节和一个(N ? M) 字节 NOP

那么为什么 gcc 会这样做呢?我们可以让它生成多字节 NOP 吗?两个 0x90 NOP 是否比微软的好mov edi, edi