我具有以下汇编(x64)函数:

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


我发现开头部分只是任何汇编程序的头。另外,我认为这两个QWORD来自long或字符。我猜jne跳转可能是一个条件语句,但是我不太确定。该函数似乎是递归的,因为它有一行再次调用“ bar”。

我对整体功能的猜测是,它需要两个long并以递归方式将它们相加(也许是斐波那契)。我对此猜测没有太多理由,而且我可能是不正确的。

有人可以帮我解决这个问题吗?或者,如果我有办法传递参数(我什至不知道函数采用哪种参数)并查看输出,那么我可以尝试回溯并弄清楚程序在做什么。

感谢

评论

为什么删除函数的汇编代码?请注意,这仍将存储在问题的历史记录中...

从问题中删除有用的内容是很不容易的,特别是如果您得到了答案。如果您不希望其他人阅读此内容,则不应该先将其发布。

#1 楼

此函数(以递归方式)计算n前整数的和:

     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)


最终代码:

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


坦率地说,我会使用众所周知的公式n*(n+1)/2 ...

评论


真想知道您是怎么到达的... :)

–伊戈尔·斯科钦斯基♦
18-10-10在19:46

是的,但这很简单……:)(我知道,这不是没有详细解释的借口)。

–恐怖
18-10-11在7:56