2015-12-07 1 views
-1

У меня есть этот код:Как заставить GCC производить SCAN REPNE (сборка x86), а не CMP?

void main() { 
    short int a[5]={12,15,1,17,248}; 
    short int i=0; 
    short int b=17; 
    for (;i<(sizeof a/sizeof *a);i++) { 
     if (a[i]==b) printf("Hello, %d\n",i); 
    } 
} 

И я ожидаю увидеть REPE SCASW в сгенерированном коде сборки. Но независимо от уровня оптимизации (я пытался -О 0,1,2,3) GCC генерирует просто цикл с имп и драг, такие как (я получил его с objdump):

3f: 48 83 fb 05    cmp rbx,0x5 
    43: 74 2b     je  70 <main+0x70> 
     if (a[i]==b) printf("Hello, %d\n",i); 
    45: 66 83 3c 5c 11   cmp WORD PTR [rsp+rbx*2],0x11 
    4a: 75 ec     jne 38 <main+0x38> 

Кто может сказать мне, почему GCC не использует инструкцию REPNE SCAS x86 в таком простом случае? Может быть, scas слишком медленный по сравнению с петлей с 2 ​​"cmp" s и 2 "je? S?

И могу ли я заставить GCC использовать SCAS с префиксом REPNE?

Заранее благодарен!

+0

Зачем вам все равно? – DarkDust

+0

Вы не подразумеваете 'repne scas'? – harold

+0

«Разве вы не имеете в виду« красные сказки » Да, конечно, извините. – drvtiny

ответ

1

Вы не указали, почему вы, кажется, думаете, что должны видеть REPNE SCAS, но независимо от уровня оптимизации вы не должны его видеть.

Если вы обратитесь к Agner Fog таблиц (последнее обновление в 2014 году), вы увидите, что REPNE SCAS является всегда менее оптимальным, чем CMP с последующим JE.

Вы действительно не можете заставить компилятор пойти по этому маршруту, но если вам нужно будет создать этот конкретный код, вам лучше всего воспользоваться встроенным сборочным маршрутом.

+0

Циклический счет чреват опасностью, но, как правило, строковые инструкции не были хорошим выбором для оптимизации скорости для чего-либо после 386. :-) –

+0

Правда , но цифры настолько экстремальные ... –