4

私の通常のVC++レルムからGCCの世界への冒険(MINGW32経由)。主にNOPで構成されるWindowsPEを作成しようとすると、次のようになります。

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

しかし、私が間違った構文を使用しているか、コンパイラーがそれらを介して最適化しています。これらのNOPはコンパイルプロセスに耐えられないためです。

-O0フラグを使用していますが、それ以外の場合はデフォルトです。コンパイラを誘導してNOPをそのままにしておく方法についてのアイデアはありますか?

4

3 に答える 3

6

1000インラインを取得する便利な方法は、GNUアセンブラのディレクティブnopを使用することです。.rept

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

godboltを試してみてください

于 2020-10-23T04:02:38.477 に答える
5

ループを1000秒に展開することを期待していますnopか?で簡単なテストを行いましたが、(1つ)が消える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にループすることに関するこの最近の質問は、テンプレートの再帰を使用した巧妙な答えをもたらしました。これは、まったくnop繰り返さずに1000関数を生成するために実際に使用できますasm("nop")。いくつかの注意点があります。コンパイラーに関数をインライン化させないと、個々のnop関数の1000の深さの再帰スタックになってしまいます。また、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 に答える