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++ 코드는 다음과 같습니다
le_uint32_t
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;
는 빅 엔디안 시스템에서 바이트 스왑 작업을 래핑하는 클래스입니다. x86에서는 아무것도하지 않습니다. used_p()
함수는지도 기본 + 오프셋에서 포인터를 계산하고 올바른 유형의 포인터를 반환합니다.
참조 http://stackoverflow.com/questions/2703394/whats-the-point-of-lea-eax-eax – nos
@nos : 아마도 가능합니다. 그러나 GCC는 어떤 이유로 그곳에 nop을 원하는가? 맞출 것이 없습니다. –
SHL 명령의 주소가 바이트로만 정렬됩니다. 정렬 할 항목이있는 경우 (다음 명령에 착륙 할 필요가없는 점프 어딘가), 그렇지 않습니다. 이것은 단지 최적화 도구 버그처럼 보입니다. 다른 플래그와 더 최근의 gcc 버전 (4.4.3은 상당히 오래되었습니다)을 시험해보고 어떤 효과가 있는지보십시오. –