day2_シフト演算
自分の中でピンとこなかったシリーズなので記事化
そもそもシフト演算ってなんだろ、というところから。
シフト演算は掛け算/割り算の代わりに利用すると処理が高速になるとのこと。
int Calc() { unsigned int a = 10; //20 printf("左シフト : %d\n", a << 1); //5 printf("右シフト : %d\n", a >> 1); return 0; }
逆アセも一緒に見てみた
000A42F0 push ebp
000A42F1 mov ebp,esp
000A42F3 sub esp,0D8h
000A42F9 push ebx
000A42FA push esi
000A42FB push edi
000A42FC lea edi,[ebp-0D8h]
000A4302 mov ecx,36h
000A4307 mov eax,0CCCCCCCCh
000A430C rep stos dword ptr es:[edi]
000A430E mov ecx,offset _D0BBC2EA_Source@cpp (0AC003h)
000A4313 call @__CheckForDebuggerJustMyCode@4 (0A121Ch)
000A4318 mov dword ptr [a],0Ah
000A431F mov eax,dword ptr [a]
000A4322 shl eax,1
000A4324 push eax
000A4325 push offset string "d\n" (0A7BD8h)
000A432A call _printf (0A1046h)
000A432F add esp,8
000A4332 mov eax,dword ptr [a]
000A4335 shr eax,1
000A4337 push eax
000A4338 push offset string "\x8d\xb6\x83V\x83t\x83g : %d\n" (0A7BE8h)
000A433D call _printf (0A1046h)
000A4342 add esp,8
000A4345 xor eax,eax
000A4347 pop edi
000A4348 pop esi
000A4349 pop ebx
000A434A add esp,0D8h
000A4350 cmp ebp,esp
000A4352 call __RTC_CheckEsp (0A1226h)
000A4357 mov esp,ebp
000A4359 pop ebp
000A435A ret
なるほど、lとrがleft,rightを示しているっぽい。
1行のニーモニックで処理が完結できることから、処理が高速といわれてるんだろうか。
シフト演算なしの乗算/除算を試してみてコードに変化があるか確認してみる。
int Calc2() {
unsigned int a = 10;
printf("乗算:%d\n", a * 2);
printf("除算:%d\n", a / 2);
return 0;
}
push ebp
006542F1 mov ebp,esp
006542F3 sub esp,0CCh
006542F9 push ebx
006542FA push esi
006542FB push edi
006542FC lea edi,[ebp-0CCh]
00654302 mov ecx,33h
00654307 mov eax,0CCCCCCCCh
0065430C rep stos dword ptr es:[edi]
0065430E mov ecx,offset _D0BBC2EA_Source@cpp (065C003h)
00654313 call @__CheckForDebuggerJustMyCode@4 (065121Ch)
00654318 mov dword ptr [a],0Ah
0065431F mov eax,dword ptr [a]
00654322 shl eax,1
00654324 push eax
00654325 push offset string "d\n" (0657BD8h)
0065432A call _printf (0651046h)
0065432F add esp,8
00654332 mov eax,dword ptr [a]
00654335 shr eax,1
00654337 push eax
00654338 push offset string "\x8f\x9c\x8eZ:%d\n" (0657BE8h)
0065433D call _printf (0651046h)
00654342 add esp,8
00654345 xor eax,eax
00654347 pop edi
00654348 pop esi
00654349 pop ebx
0065434A add esp,0CCh
00654350 cmp ebp,esp
00654352 call __RTC_CheckEsp (0651226h)
00654357 mov esp,ebp
00654359 pop ebp
0065435A ret
残念ながら期待していた違いは得られなかった。
おそらくVisual Studioではコンパイラが最適化しているんだろうか。
全然別のネタに発展してしまったが、私が理解したかったのは
左シフト:値 * (2^n)
右シフト:値 / (2^n)
ということ。
いやほんとに全然違うこと調べんじゃん。