gcc -S sembra un po 'deformato con i bit shift e ANDing

2

Esempio:

int c = 4;
int p = 5;

if (p & (1 << c))
   printf("ok\n");
else
   printf("nop\n");

gcc -S:

movl    -4(%rbp), %eax   /* eax holds the variable c  */
movl    -8(%rbp), %edx   /* and edx holds p  */
movl    %eax, %ecx       /* tmp(ecx) = c  */
sarl    %cl, %edx        /* edx(p) >>= c  */
movl    %edx, %eax       /* eax = p shifted right by c */
andl    $1, %eax         /* eax(p shifted right by c) &= 1  */
testl   %eax, %eax       /* test if p is 0  */
... jumps and such ...

Come puoi vedere, GCC per qualche ragione ha convertito il mio codice in:

p >>= c;
p &= 1
if (p != 0)
    ...
else
    ...

Qualcosa di strano sta succedendo qui o mi manca qualcosa ... Ha fatto l'operazione all'indietro, anche se avevo parentesi attorno al 1 << c quindi avrebbe dovuto farlo separatamente E AND con p corretto?

Qualcuno può spiegare perché GCC ha fatto questo? È una sorta di ottimizzazione (non ho abilitato l'ottimizzazione quando ho compilato questo, quindi ne dubito) O è come dovrebbe essere fatto in assembly?

    
posta nobby 20.06.2014 - 17:51
fonte

2 risposte

2
(1<<c) set the fifth bit. == 0x10 (==16 dec)

p & (1<<c)

La condizione qui è: "Il 5 ° bit è impostato nella variabile p?"

Per ottenere questo test puoi spostare p a destra per 4 e chiedere "è il bit più basso impostato?" quindi il tuo codice è stato convertito in     if ((p > 4) & 0x1)

Qual è la stessa cosa.

esegui gcc -S -O3 e la stessa logica collassa in

btl %edi, %esi
jc  .L4
    
risposta data 26.08.2014 - 09:02
fonte
4

È probabile una sorta di ottimizzazione. Non tutte le ottimizzazioni devono essere esplicitamente abilitate. I più sicuri saranno abilitati a meno che non siano esplicitamente disabilitati, il che sembra essere il caso qui. L'esecuzione del seguente comando sul mio sistema mostra 47 ottimizzazioni abilitate di default:

gcc -Q --help=optimizers
    
risposta data 20.06.2014 - 18:34
fonte

Leggi altre domande sui tag