assemblyx86intelinteger-divisionsign-extension

IA-32 assembly divison


Can somebody explain to me the following snippet of assembly:

mydiv:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %edx  ; get x
        movl    %edx, %eax
        sarl    $31, %edx      ; divide by y
        idivl   12(%ebp)       ; return %eax
        popl    %ebp
        ret

This is the equivalent to the following C function:

int mydiv( int x, int y )
{
    return x / y;
}

The part which I'm having trouble understanding is the sarl instruction: why do you need to shift edx?


Solution

  • It's sign extending.

    idivl has a 64-bit argument (edx:eax), so you need to ensure that the MSB contains the correct sign bits, based on the msb of eax.

    So if eax is positive, it's msb will be 0, e.g. 5 -> 0000 ... 0101. If it's negative it's msb will be 1, e.g. -5 -> 1111 ... 1011. sarl performs an arithmetic right-shift, so edx will either be 0000 ... 0000 or 1111 ... 1111.