10

I think this is actually a pretty simple problem. I have to reverse engineer this assembly code to c code. I'll also provide what I think is going on so you can hopefully point to where I went wrong and I can learn from my mistakes now.

.LFBO
    pushq   %rbp
    movq    %rsp,%rbp
    movl    %edi,-4(%rbp)
    movl    %esi,-8(%rbp)
    movl    -4(%rbp),%eax
    compl   -8(%rbp),%eax
    jg      .L2
    movl    -8(%rbp),%eax
    jmp     .L3
.L2:
    movl    -4(%rbp),%eax
.L3:
    popq    %rbp
    ret

So this is what I think is going on with this: the first two lines after .LFBO:

pushq   %rbp
movq    %rsp,%rbp

are just setting up the stack for the execution that is about to follow.

movl    %edi,-4(%rbp)

is grabbing the first variable, call it x

movl    %esi,-8(%rbp)

is grabbing the second variable call it y

movl    -4(%rbp),%eax

is grabbing x to be compared in the next line

compl   -8(%rbp),%eax

compares the variables x and y by computing x-y

jg      .L2

says jump to .L2 if x > y

if x <= y then compute the next lines without jumping to .L2

movl    -8(%rbp),%eax

copy x = y

jmp     .L3

jump to .L3

if x > y at the jg line then you jump to .L2: and complete this line

movl    -4(%rbp),%eax

this is where I realized I was really confused. It looks to me that you're copying x to x then .L3 is completed and I think x is returned

9
  • 2
    Just to confirm, this is AT&T-syntax x86 assembly? Commented Feb 12, 2015 at 23:57
  • 4
    I don't think you were confused. You are just looking at unoptimized code, so there are lines that are completely useless (like assigning x to x as you said). So what do you think the function does, given all that? Commented Feb 12, 2015 at 23:58
  • Yes, I believe this is AT&T-syntax x86 assembly. It was created from c code on a linux @Dai Commented Feb 13, 2015 at 0:06
  • So really what the code does is just take 2 variables (x and y) and then return the smaller of the two? @JS1 Commented Feb 13, 2015 at 0:07
  • If I read the assembler code and your analysis correctly, it will return the bigger one: It jumps to L2 if x is bigger, and it copies (needlessly) x into %rax at L2. Commented Feb 13, 2015 at 0:10

3 Answers 3

14

Don't overthink it. Just gradually replace the assembly with C. Here is a possible sequence of transformations.

.LFBO
    pushq   %rbp
    movq    %rsp,%rbp
    movl    %edi,-4(%rbp)
    movl    %esi,-8(%rbp)
    movl    -4(%rbp),%eax
    compl   -8(%rbp),%eax
    jg      .L2
    movl    -8(%rbp),%eax
    jmp     .L3
.L2:
    movl    -4(%rbp),%eax
.L3:
    popq    %rbp
    ret

----

int LFBO (int edi, int esi)
{
    rbp = rsp
    [rbp - 4] = edi
    [rbp - 8] = esi
    eax = [rbp - 4]
    if (eax > [rbp - 8]) goto L2
    eax = [rbp - 8]
    goto L3
L2:
    eax = [rbp - 4]
L3:
    return eax
}

----

int LFBO (int edi, int esi)
{
    int eax;

    eax = edi;
    if (eax > esi) goto L2;
    eax = esi;
    goto L3;
L2:
    eax = edi;
L3:
    return eax;
}

----    

int LFBO (int edi, int esi)
{
    int eax;

    eax = edi;
    if (eax <= esi) {
        eax = esi;
    }
    else {
        eax = edi;
    }
    return eax;
}

----

int LFBO (int edi, int esi)
{
    if (edi <= esi) {
        return esi;
    }
    else {
        return edi;
    }
}

----

int LFBO (int x, int y)
{
    if (x <= y) {
        return y;
    }
    else {
        return x;
    }
}

----

int LFBO (int x, int y)
{
    return (x > y) ? x : y;
}

You can apply this strategy to any piece of assembly. Here I took the time to detail the various transformations. With practice you can get to the end result a lot quicker.

Sign up to request clarification or add additional context in comments.

Comments

2
LFB0(int x, int y){
    if (x<=y){
        x = y;
    }else{
        x = x;
    }
    return(x);
}

This is what I think we determined to be correct, with the help of the guys in the comments.

1 Comment

@thang isn't that the same thing?
0
.LFBO
    pushq   %rbp                prolog
    movq    %rsp,%rbp           prolog
    movl    %edi,-4(%rbp)       [ebp-4] = edi
    movl    %esi,-8(%rbp)       [ebp-8] = esi
    movl    -4(%rbp),%eax       eax = [ebp-4] ie edi
    compl   -8(%rbp),%eax       cmp eax with [ebp-8] ie esi 
    jg      .L2                 ;jg requires <= 
    movl    -8(%rbp),%eax       so cutting the junk 
    jmp     .L3                 this effectively becomes
.L2:
    movl    -4(%rbp),%eax       ( edi <= esi ) ? { eax = esi } : { eax= edi} ; return;
.L3:
    popq    %rbp                epilog
    ret                         epilog

testing the hypothesis

lets compile the code in vc and test should compile unoptimized else 
clever compiler will cast away everything do 
/O1 push 10 pop eax retn;
/O2 mov eax ,10  ret

int main(void) {
int edi=8,esi=10;
if ( edi <= esi) { return esi; } else { return edi;}
}

disassembling the result

0:000> uf @eip
image00400000+0x1000:
00401000 55              push    ebp
00401001 8bec            mov     ebp,esp
00401003 83ec08          sub     esp,8
00401006 c745fc08000000  mov     dword ptr [ebp-4],8
0040100d c745f80a000000  mov     dword ptr [ebp-8],0Ah
00401014 8b45fc          mov     eax,dword ptr [ebp-4]
00401017 3b45f8          cmp     eax,dword ptr [ebp-8]
0040101a 7f07            jg      image00400000+0x1023 (00401023)

image00400000+0x101c:
0040101c 8b45f8          mov     eax,dword ptr [ebp-8]
0040101f eb05            jmp     image00400000+0x1026 (00401026)

image00400000+0x1023:
00401023 8b45fc          mov     eax,dword ptr [ebp-4]

image00400000+0x1026:
00401026 8be5            mov     esp,ebp
00401028 5d              pop     ebp
00401029 c3              ret
0:000>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.