4

走出我通常的 VC++ 领域,进入 GCC 世界(通过 MINGW32)。试图创建一个主要由 NOP 组成的 Windows PE,ala:

for(i = 0; i < 1000; i++)
{
    asm("nop");
}

但是要么我使用了错误的语法,要么编译器正在通过它们进行优化,因为这些 NOP 在编译过程中无法生存。

我正在使用 -O0 标志,否则为默认值。关于如何诱使编译器保持 NOP 完好无损的任何想法?

4

3 回答 3

6

获得 1000 个 inlinenop的便捷方法是使用 GNU 汇编器的.rept指令

void thousand_nops(void) {
    asm(".rept 1000 ; nop ; .endr");
}

试试godbolt

于 2020-10-23T04:02:38.477 回答
5

您是否期望它将循环展开到 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(); ...

于 2010-12-31T00:14:45.840 回答
3

最近这个关于在没有条件的情况下循环到 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
于 2011-01-01T20:26:53.503 回答