2012-08-10 5 views
23

GCC 4.4.3 erzeugte die folgende x86_64-Assembly. Der Teil, der mich verwirrt, ist die mov %eax,%eax. Verschieben Sie das Register zu sich selbst? Warum?Warum hat GCC mov% eax,% eax generiert und was bedeutet das?

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 

Der C++ Code für diese Funktion ist:

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; 

Ein le_uint32_t eine Klasse ist, die auf Big-Endian-Maschinen-Byte-Swap-Operationen wickelt. Auf x86 tut es nichts. Die used_p()-Funktion berechnet einen Zeiger aus der Kartenbasis + Offset und gibt einen Zeiger des richtigen Typs zurück.

+2

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

+0

@nos: Möglicherweise. Aber warum sollte der GCC dort einen Nop suchen? Es gibt nichts auszurichten. –

+0

Selbst wenn es etwas zu justieren gab (ein Sprung irgendwo, den wir nicht sehen müssen, um auf den nächsten Befehl zu landen), ist es nicht - die Adresse des SHL-Befehls ist nur auf ein Byte ausgerichtet. Dies sieht einfach wie ein Optimierungsfehler aus. Probieren Sie verschiedene Flags und neuere Versionen von gcc (4.4.3 wird ziemlich alt) und sehen Sie, welchen Effekt es hat. –

Antwort

22

In x86-64, 32-Bit-Anweisungen implizit Null-Erweiterung: Bits 32-63 sind gelöscht. Manchmal werden Sie deshalb seltsam aussehende Anweisungen sehen.

Allerdings ist die vorherige mov auch 32-Bit, so dass die obere Hälfte von %rax bereits gelöscht ist. Die mov %eax,%eax scheint ein NOP zu sein.

+0

Diese Art von NOP kann auch den Zweck der Pipeline-Optimierung dienen. – mathk

Verwandte Themen