走出我通常的 VC++ 领域,进入 GCC 世界(通过 MINGW32)。试图创建一个主要由 NOP 组成的 Windows PE,ala:
for(i = 0; i < 1000; i++)
{
asm("nop");
}
但是要么我使用了错误的语法,要么编译器正在通过它们进行优化,因为这些 NOP 在编译过程中无法生存。
我正在使用 -O0 标志,否则为默认值。关于如何诱使编译器保持 NOP 完好无损的任何想法?
您是否期望它将循环展开到 1000nop
秒?我做了一个快速测试,gcc
我没有看到(一个)nop
消失:
xorl %eax, %eax
.p2align 4,,7
.L2:
#APP
nop
#NO_APP
addl $1, %eax
cmpl $1000, %eax
jne .L2
我gcc -S -O3 -funroll-all-loops
看到它展开循环 8 次(因此 8 nop
)但我认为如果你想要 1000 它将是最容易做到的:
#define NOP10() asm("nop;nop;nop;nop;nop;nop;nop;nop;nop;nop")
然后使用NOP10(); ...
最近这个关于在没有条件的情况下循环到 1000的问题使用模板递归得到了一个聪明的答案,它实际上可以用来生成你的 1000nop
函数而根本不重复asm("nop")
。有一些警告:如果你没有让编译器内联函数,你最终会得到一个 1000 深的单个nop
函数的递归堆栈。此外,gcc
的默认模板深度限制为 500,因此您必须明确指定更高的限制(见下文,尽管您可以简单地避免超过nop<500>()
)。
// compile time recursion
template<int N> inline void nop()
{
nop<N-1>();
asm("nop");
}
template<> inline void nop<0>() { }
void nops()
{
nop<1000>();
}
编译:
g++ -O2 -ftemplate-depth=1000 ctr.c