GCC NOPs компилируется - PullRequest
       10

GCC NOPs компилируется

3 голосов
/ 31 декабря 2010

Выход из моего обычного царства VC ++ в мир GCC (через MINGW32). Попытка создать Windows PE, которая состоит в основном из NOP, ала:

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

Но либо я использую неправильный синтаксис, либо компилятор оптимизирует их, поскольку эти NOP не выживают в процессе компиляции.

Я использую флаг -O0, в противном случае по умолчанию. Любые идеи о том, как я могу уговорить компилятор оставить нетронутыми NOP?

Ответы [ 2 ]

2 голосов
/ 01 января 2011

Этот недавний вопрос о цикличности до 1000 без условий привел к умному ответу с использованием рекурсии шаблона, который фактически может быть использован для получения вашей функции 1000 nop без повторения 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
2 голосов
/ 31 декабря 2010

Вы ожидаете, что он развернет цикл до 1000 nop с? Я сделал быстрый тест с 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(); ...

...