【发布时间】:2014-05-29 10:30:16
【问题描述】:
我正在尝试在汇编中编写一个递归组合函数(Yasm(类似于nsam))。 我不能使用循环、乘法或除法。
我确定我在正确的轨道上,但是一旦我点击第二个内部函数调用就会遇到问题。谁能帮助我并告诉我哪里出错了?
编辑:这是我更新的代码,它返回一个结果,但并不总是正确的。我想我一定有一点逻辑不正确。
mov rax, [n]
push rax
mov rax, [k]
push rax
call func
... ... program continues from here
func:
push rbp
mov rbp, rsp
push rdi
push rsi
cmp rsi, 0
je stopcond
cmp rdi, rsi
jne contin
stopcond:
mov rax, 1
jmp endfunc
contin:
;C(n-1,k-1)
mov rax, [rsp] ; This is k
dec rax
mov rdx, rax
mov rax, [rsp+8] ; This is n
dec rax
mov rsi, rdx
mov rdi, rax
call func
mov rbx, rax
mov rax, [rsp+8] ; This is n
dec rax
mov rdx, rax
mov rax, [rsp] ; This is k
mov rsi, rax
mov rdi, rdx
call func
add rax, rbx
endfunc:
add rsp, 16
pop rbp
ret
这是我一直用作参考的 javascript 实现
function(n,k) {
if ( k==0 || k==n ) {
return 1
} else {
return C(n-1,k-1) + C(n-1,k)
}
}
【问题讨论】:
-
如果这是您的所有代码,那么当
func最终返回时您将遇到问题,因为func:直接跟随call func。 -
这就是我的想法,但是当我查看此
int func(int n,int k){if(k==0||k==n){return 1;}else{return func(n-1,k-1)+func(n-1,k);}}此处assembly.ynh.io 的c->汇编转换时,他们做了非常相似的事情@Michael -
该 C 代码不包括对
func的初始调用。 -
这就是这里,唯一有趣的是它把
n和k分别放入edi和esiint func(int n,int k){if(k==0||k==n){return 1;}else{return func(n-1,k-1)+func(n-1,k);}}int main(){int a=func(3,2);return 0;} -
如果您在该网站上查看程序集输出,需要注意的一些重要事项是 A) 从
main到func的调用位于 之后func的主体,而不是像您的代码中那样在它之前,并且 B)在func返回到main之后,有一个ret返回到调用main函数的 C 运行时。
标签: assembly recursion x86-64 pascals-triangle yasm