2012-08-10 14 views
23

GCC 4.4.3 wygenerował następujący zestaw x86_64. Częścią, która mnie myli, jest mov %eax,%eax. Przenieść rejestr do siebie? Czemu?Dlaczego GCC generuje mov% eax,% eax i co to znaczy?

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++ kod dla tej funkcji jest następująca:

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 to klasa, która owija operacji bajt-swap na maszynach big-endian. Na x86 nic nie robi. Funkcja used_p() oblicza wskaźnik z podstawy mapy + przesunięcie i zwraca wskaźnik odpowiedniego typu.

+2

Zobacz http://stackoverflow.com/questions/2703394/whats-the-point-of-lea-eax-eax – nos

+0

@nos: Możliwe. Ale z jakiego powodu GCC chciałby mieć tam nop? Nie ma nic do wyrównania. –

+0

Nawet jeśli było coś do wyrównania (skoku gdzieś nie widzimy potrzeby wylądowania na następnej instrukcji), to nie jest - adres instrukcji SHL jest wyrównany tylko do bajtu. To po prostu wygląda jak błąd optymalizatora. Wypróbuj różne flagi i nowsze wersje gcc (4.4.3 jest coraz bardziej nieaktualna) i zobacz, jaki ma efekt. –

Odpowiedz

22

W x86-64, instrukcje 32-bitowe niejawnie zerowe rozciągnięcie: bity od 32 do 63 są kasowane. Czasami dlatego widzisz dziwacznie wyglądające instrukcje.

Jednak poprzednie mov jest również 32-bitowe, więc wysoka połowa %rax jest już wyczyszczona. Model mov %eax,%eax wydaje się być NOP.

+0

tego rodzaju NOP może również służyć do optymalizacji rurociągów. – mathk