Search code examples
cassemblyx86bit-manipulationbit-shift

How can I do these asm ROR and BT/RCR operations in C? Rotate, or shift in a bit from another number


I'm converting some assembly code to C to be able to use it with the current compiler environment I have to work with.

I've reached 2 operations I don't know how to translate to C. Anyone know how to do it?

In both, offset is an unsigned 32-bit integer and shift is a signed integer value. C_FLAG is a bool.

OP1:

__asm {
    __asm mov ecx, shift
    __asm ror offset, cl
}

OP2:

__asm {
    __asm bt dword ptr C_FLAG, 0
    __asm rcr offset, 1
}

Thank you very much for your expertise.

P.S.: I'm not the original developer, nor I have seen many x86 assembly code...


Solution

  • Assuming that the flags are not used to hold persistent state (which is a reasonable assumption), OP1 is equivalent to:

    /* Precondition: `*offset` is in range 0..0xFFFFFFFF */
    void inline op1(unsigned long *offset, int shift)
    {
        shift = ((unsigned)shift) % 32;
    
        if (shift)
            *offset = ((*offset >> shift) | (*offset << (32 - shift))) & 0xFFFFFFFFUL;
    }
    

    and OP2 is equivalent to:

    /* Precondition: `*offset` is in range 0..0xFFFFFFFF */
    void inline op2(unsigned long *offset, unsigned long C_FLAG)
    {
        *offset = (*offset >> 1) | ((C_FLAG & 1) << 31);
    }
    

    (On systems with 32 bit long, the precondition is automatically satisfied).