Search code examples
cmathassemblyx86instructions

Reading Math Functions in Assembly


I'm translating a bit of x86 Assembly to C code. A small section of the assembly is giving me trouble.

mov %eax, %edx
sar $0x1f, %edx
idivl -0x18(%ebp)
mov %edx, %eax

Our eax value starts off with 0 in it. Then we shift and rotate by 0x1f (31). I know that shift right is divide by 2...what happens if you shift and rotate to a number? Is it also /2? Then we divide by the element at space -0x18(%ebp) which we'll call int x. Or does idivl work in a different way? Then we put it back into %eax and I get the rest of the program easily.

Some help would be appreciated. The main thing I don't understand is the sar instruction


Solution

  • This snippet of assembly just performs a signed 32-bit modulo operation:

    a %= x;
    

    The sar instruction is an arithmetic right shift (a right shift which preserves the sign of the operand); looking at the first two instructions:

    mov %eax, %edx
    sar $0x1f, %edx
    

    This sign-extends the contents of %eax into the double register %edx:%eax; in pseudo-C code:

    edx_eax = (int64_t)eax;
    

    The next two instructions:

    idivl -0x18(%ebp)
    mov %edx, %eax
    

    perform a signed 64-bit divide, with the resulting remainder in %edx, which is then transferred to %eax. In pseudo-C code again:

    edx = (int32_t)(edx_eax % x);
    eax = edx;