Search code examples
cassemblyx86-64reverse-engineering

x86-64 Assembly Loop


This question was proposed to me by a friend and I have no idea how to solve it.

loop:
    leal (%rdi, %rdi, 4), %eax
    leal (%rsi, %rax, 2), %eax
    leal 0(, %rax, 4), %edx
    cmpl %edx, %esi
    jge .L1
    leal (%rdi, %rdi, 2), %edx
.L3:
    addl %edx, %eax
    cmpl $-2, %esi
    jl .L3
.L1:
    rep ret

And is supposed to map to this loop in C,

int loop(int a, int b){
    int x, y;
    y = ____;
    for (____; ____; ____){
        ____;
    }
    return ____;
}

My attempt at converting the assembly to C,

y = 5a;
y = b + 2y;
x = 4y;
if (x < b){
    x = 3a;
    do{
        y += x;
    } while (b <= -2);
}
return y;

I assumed %eax = y, since 'y' in the code to fill is the first variable being assigned. 'x' follows as %edx since it's another assignment, and so should be at least part of the "Initialisation" of the for loop. However this doesn't seem to fix into the blanks provided, so I am really stuck.


Solution

  • I think I've got a really close, if not perfect solution:

    /* rdi = a, rsi = b */
    /* rax = y, rdx = x */
    
    /*
    loop:
        leal (%rdi, %rdi, 4), %eax
        leal (%rsi, %rax, 2), %eax
        leal 0(, %rax, 4), %edx
        cmpl %edx, %esi
        jge .L1
        leal (%rdi, %rdi, 2), %edx
    .L3:
        addl %edx, %eax
        cmpl $-2, %esi
        jl .L3
    .L1:
        rep ret
    */
    
    int loop(int a, int b){
        int x, y;
        y = b + (a * 5) * 2;
        for (x = y * 4; x > b;){
            do y += (x = a * 3); while(b < -2);
            break;
        }
        return y;
    }
    

    Not sure if break; is an issue but I can't find a better way.