GCC 4.4.3が次のx86_64アセンブリを生成しました。私を混乱させる部分はmov %eax,%eax
です。レジスタを自分自身に移動しますか?どうして?なぜGCCはmov%eax、%eaxを生成しましたか?それはどういう意味ですか?
23b6c: 31 c9 xor %ecx,%ecx ; the 0 value for shift
23b6e: 80 7f 60 00 cmpb $0x0,0x60(%rdi) ; is it shifted?
23b72: 74 03 je 23b77
23b74: 8b 4f 64 mov 0x64(%rdi),%ecx ; is shifted so load shift value to ecx
23b77: 48 8b 57 38 mov 0x38(%rdi),%rdx ; map base
23b7b: 48 03 57 58 add 0x58(%rdi),%rdx ; plus offset to value
23b7f: 8b 02 mov (%rdx),%eax ; load map_used value to eax
23b81: 89 c0 mov %eax,%eax ; then what the heck is this? promotion from uint32 to 64-bit size_t?
23b83: 48 d3 e0 shl %cl,%rax ; shift rax/eax by cl/ecx
23b86: c3 retq
この機能のためのC++のコードは次のとおりです。
uint32_t shift = used_is_shifted ? shift_ : 0;
le_uint32_t le_map_used = *used_p();
size_t map_used = le_map_used;
return map_used << shift;
le_uint32_t
はビッグエンディアンのマシンでバイトスワップ操作をラップするクラスです。 x86では何もしません。 used_p()
関数は、マップの基数+オフセットからポインタを計算し、正しい型のポインタを返します。
参照http://stackoverflow.com/questions/2703394/whats-the-point-of-lea-eax-eax – nos
@nos:おそらく。しかし、GCCはどんな理由でそこにノブを望んでいますか?整列するものは何もありません。 –
SHL命令のアドレスは1バイトにのみ整列されます(次の命令に着地する必要がない場所にジャンプする)何かがあったとしても、そうではありません。これはちょうどオプティマイザのバグのようです。別のフラグと最近のバージョンのgcc(4.4.3はかなり古くなっています)を試してみて、どのような効果があるかを見てください。 –