2

I have been struggling with this for a long time. I have the following assembly language code:

.intel_syntax noprefix
.bits 32

.global asm0

asm0:
    push    ebp
    mov ebp,esp
    mov eax,DWORD PTR [ebp+0x8]
    mov ebx,DWORD PTR [ebp+0xc]
    mov eax,ebx
    mov esp,ebp
    pop ebp 
    ret

and I want to figure out what asm(0xb6, 0xc6) returns. I've been looking for ASM->C decompilers etc, and I cannot find anything for free. Could someone please help me decipher this? I've been trying for a really long time. I am familiar with C++ and Java programming, so even some sort of tool to convert it would be helpful.

I'm currently reading from this: http://www.godevtool.com/GoasmHelp/newass.htm

1 Answer 1

8

This is such a small program so this could be followed without converting it back to C. Let's break it down what happens when it's being called with asm(0xb6, 0xc6).

push    ebp
mov     ebp, esp

Those two lines are what's is called the function prologue. We first save the calling function stack frame (ebp is tracking that) and in the second one, we set our function stack frame to be equal to the current stack location.

mov eax, DWORD PTR [ebp+0x8]
mov ebx, DWORD PTR [ebp+0xc]

The above lines are loading our passed arguments to eax and ebx. Since in cdecl arguments are passed via stack in reverse order, so after those lines in eax we will have 0xb6 and ebx will be equal to 0xc6.

mov eax, ebx

The value from ebx is stored in eax, thus we drop the need of the first line from the previous fragment. Also since this is the last use of eax in this code it can be interpreted as a return value as this is also a convention in cdecl. So the return value, in this case, would be 0xc6.

mov esp,ebp
pop ebp

This is just bringing back the stack as it was when we enter the function - also called function epilogue.

ret

And return back to the caller.

Having analyzed that it's just obvious that this function returns the second argument that's being passed to it.

int second(int a, int b)
{
    return b;
}

You could compile this code to a library and use it from C code:

#include <stdio.h>

extern unsigned int _test (unsigned int, unsigned int);

int main(void)
{
    printf("%x\n", _test(0xb6, 0xc6));
    return 0;
}

and compile it with gcc -m32 -o run asm.o call.o.

./run
c6

You could verify that it's the case without running it by for example using godbolt but since the code that assigns the first value to eax and then replaces it with the second is actually not needed - it could just use the second argument from the beginning - it won't be generated even w/o any optimizations.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.