I have the following assembly (x64) function:

400700: sub  rsp,0x18
400704: mov  QWORD PTR [rsp+0x8],rdi
400709: cmp  QWORD PTR [rsp+0x8],0x0
40070f: jne  400718 <bar+0x18>
400711: mov  eax,0x0
400716: jmp  400734 <bar+0x34>
400718: mov  rax,QWORD PTR [rsp+0x8]
40071d: sub  rax,0x1
400721: mov  rdi,rax
400724: call 400700 <bar>
400729: mov  rdx,rax
40072c: mov  rax,QWORD PTR [rsp+0x8]
400731: add  rax,rdx
400734: add  rsp,0x18
400738: ret

I've figured out that the beginning part is just the header for any assembly program. Also, I think that the two QWORD are either from longs or characters. I'm guessing that the jne jump is probably a conditional statement, but I'm not too sure. It looks like the function is recursive since it has a line that calls "bar" again.

My guess for the overall function is that it takes two longs and recursively adds them (Fibonacci, maybe?). I don't have much reasoning for this guess though, and I could be incorrect.

Could anyone please help me solve this problem? Or, if there's a way for me to pass in parameters (I don't even know what kind of argument the function takes) and see the output, then I can try to backtrack and figure out what the program is doing.

Thanks

  • 1
    Why did you remove the assembly code of the function? Note that, this will still be stored in the history of the question... – perror Oct 10 at 8:07
  • 1
    Removing useful content from a question is highly frowned upon, especially if you got an answer. If you do not want others to read this, you should not have posted it to begin with. – usr2564301 Oct 10 at 8:33
up vote 4 down vote accepted

This function computes (in a recursive manner) the sum of the n first integers:

     400700: sub  rsp,0x18                 ; Align the stack
     400704: mov  QWORD PTR [rsp+0x8],rdi  ; Store first argument on stack
     400709: cmp  QWORD PTR [rsp+0x8],0x0  ; test (n == 0)
  +--40070f: jne  400718 <bar+0x18>        ; jump to 400718 if (n != 0)
  |  400711: mov  eax,0x0                  ; set return code to zero
+-|--400716: jmp  400734 <bar+0x34>        ; jump to function end at 400734
| +->400718: mov  rax,QWORD PTR [rsp+0x8]  ; Get 'n' in rax
|    40071d: sub  rax,0x1                  ; n = n - 1
|    400721: mov  rdi,rax                  ; Load 'n - 1' as first argument
|    400724: call 400700 <bar>             ; recursive call to 'bar(n - 1)'
|    400729: mov  rdx,rax                  ; Load bar(n-1) return code in rdx
|    40072c: mov  rax,QWORD PTR [rsp+0x8]  ; Get current 'n' in rax
|    400731: add  rax,rdx                  ; rax = n + bar(n - 1)
+--->400734: add  rsp,0x18                 ; Restore the stack
     400738: ret                           ; return n + bar(n - 1)

Final code:

bar (long long int n)
{
  return (n) ? n + bar(n - 1) : 0;
}

Frankly, I would have used the well known formula n*(n+1)/2...

  • would have been nice to see how you arrived to this... :) – Igor Skochinsky Oct 10 at 19:46
  • Yes, but that was quite straight forward... :) (I know, this is not an excuse to not explain it in details). – perror Oct 11 at 7:56

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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