Для такого кода:
int res = 0;
for (int i = 0; i < 32; i++)
{
res += 1 << i;
}
Этот код генерируется (режим выпуска, отладчик не подключен, 64 бита):
xor edx,edx
mov r8d,1
_loop:
lea ecx,[r8-1]
and ecx,1Fh ; why?
mov eax,1
shl eax,cl
add edx,eax
mov ecx,r8d
and ecx,1Fh ; why?
mov eax,1
shl eax,cl
add edx,eax
lea ecx,[r8+1]
and ecx,1Fh ; why?
mov eax,1
shl eax,cl
add edx,eax
lea ecx,[r8+2]
and ecx,1Fh ; why?
mov eax,1
shl eax,cl
add edx,eax
add r8d,4
cmp r8d,21h
jl _loop
Теперь я вижу смысл большинства инструкций, но что там с инструкциями AND? ecx никогда не будет больше 0x1F в этом коде в любом случае, но я извиняюсь за то, что не заметил этого (а также за то, что не заметил, что результат является константой), это не опережающий компилятор, который может позволить себе тратить много времени на анализ в конце концов. Но что еще более важно, SHL с 32-битным операндом маскирует уже значение 0x1F. Поэтому мне кажется, что эти AND совершенно бесполезны. Почему они генерируются? У них есть какая-то цель, по которой я скучаю?