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
评论
为什么删除函数的汇编代码?请注意,这仍将存储在问题的历史记录中...从问题中删除有用的内容是很不容易的,特别是如果您得到了答案。如果您不希望其他人阅读此内容,则不应该先将其发布。