2012-05-25 25 views
8

Dla tego kawałka kodu C:Dlaczego gcc movl do tego samego rejestru?

uint64_t roundUp(uint64_t value, uint32_t blockSize) 
{ 
    return (value + blockSize - 1) & ~(blockSize - 1); 
} 

gcc 4.6 -O3 wygenerowany następujący montaż:

roundUp(unsigned long, unsigned int): 
.LFB0: 
    .cfi_startproc 
    movl %esi, %edx 
    movl %esi, %esi 
    leaq -1(%rdi,%rsi), %rax 
    negl %edx 
    andl %edx, %eax 
    ret 
    .cfi_endproc 

Czy ktoś może mi powiedzieć, dlaczego ona chce to zrobić?

movl %esi, %esi 

Odpowiedz

10

To usuwa górne 32 bity. Kiedy zapisujesz do rejestru 32-bitowego w x86-64, 32-bitowe bity są kasowane automatycznie. Ponieważ esi zawiera parametr 32-bitowy, górne 32 bity mogą zawierać dowolną wartość, więc muszą być usunięte, aby można było użyć rsi.

+0

ale instrukcja bezpośrednio powyżej pisze do esi – wowest

+1

@wowest Nie, to nie jest składnia intel. Operand przeznaczenia jest drugim. –

+0

@ughoavgfhw to oświecające, dzięki. Czy chciałbyś również wyjaśnić, w jaki sposób (blockSize - 1) kończy się w% edx? Widzę, jak kończy się blockSize, ale blockSize - 1? –

Powiązane problemy