GCC NOPs компилируется
Выход из моего обычного царства VC++ в мир GCC (через MINGW32). Попытка создать Windows PE, которая состоит в основном из NOP, аля:
for(i = 0; i < 1000; i++)
{
asm("nop");
}
Но либо я использую неправильный синтаксис, либо компилятор оптимизирует их, потому что эти NOP не выживают в процессе компиляции.
Я использую флаг -O0, в противном случае по умолчанию. Любые идеи о том, как я могу уговорить компилятор оставить нетронутыми NOP?
4 ответа
Ожидаете ли вы, чтобы развернуть цикл до 1000 nop
s? Я сделал быстрый тест с 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 инлайн
nop
s - использовать .rept
директива ассемблера GNU:
void thousand_nops(void) {
asm(".rept 1000 ; nop ; .endr");
}
Этот недавний вопрос о цикличности до 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
в дополнение к ответу @BenJackson, он может рекурсировать с гораздо меньшей глубиной за счет (двоичного) деления.
template<unsigned int N> inline void nop()
{
nop<N/2>();
nop<N/2>();
nop<N-2*(N/2)>();
}
template<> inline void nop<0>() { }
template<> inline void nop<1>() { asm("nop"); }