Home > Enterprise >  Translating RCL assembly into C/C
Translating RCL assembly into C/C

Time:02-03

I'm trying to manually translate some assembly into C/C in order to migrate a code-base to x64 bit as Visual Studio does not allow __asm code to compile in x64 bit.

I've translated some parts, however I am stuck on the following (it's an extract from the full function but should be self-contained):

void Foo()
{
    char cTemp = ...;
    int iVal = ...;

    __asm
    {
        mov ebx, iVal

        mov dl, cTemp
        mov al, dl

        MOV CL, 3

        CLC

        MOV AX, BX
        ROR AH, CL
        XOR DL, AH
        SAR DL, 1
        RCL BX, 1
        RCL DL, 1
    }
}

The parts I'm struggling with are:

RCL BX, 1
RCL DL, 1

From what I understand this is the equivalent of the following:

short v = ...;
v = (v << 1)   (CLEAR_FLAG ? 1 : 0)

Which from my understanding means if the value of (v << 1) overflows then add 1, otherwise add 0 (I may be mis-understanding though, so please correct me if so).

What I'm struggling to do is detect the overflow in C/C when carrying the shift operation. I've looked around and the only thing I can find is detecting addition/subtraction overflow before it happens, but nothing with regards to bit shifting.

Is it possible at all to translate such assembly to C/C ?

CodePudding user response:

RCL is a "rotate left with carry" operation. So you need to take into account the previous instruction, SAR, that sets the carry flag (CF).

Note that SAR is a signed right shift, so will need a signed operand. It important to use proper data types that match the instruction precisely in bitness and signedness.

A 1-to-1 translation could look something like this

int8_t dl = /* ... */;
uint16_t bx = /* ... */;

//           SAR DL,1
int8_t carry_1 = dl & 1;
dl >>= 1;

//           RCL BX,1
uint16_t carry_2 = bx >> 15;
bx = (bx << 1) | carry_1;

//           RCL DL,1
dl = (dl << 1) | carry_2;

There is probably a way to simplify these further. There are tools that can do that, they provide a somewhat readable C equivalent for a decompiled function.

  • Related