【问题标题】:Recursive Ackermann-Peter Function in x86 Assembly (NASM)x86 汇编 (NASM) 中的递归 Ackermann-Peter 函数
【发布时间】:2011-06-02 16:11:53
【问题描述】:

我试图在 x86 NASM-Assembly 中实现递归 Ackermann-Peter-Function。函数定义如下:

*a(0;m) = m + 1

*a(n + 1; 0) = a(n; 1)

*a(n + 1;m + 1)) = a(n;a(n + 1;m))

我的问题是我什至无法想象如何正确启动。到目前为止,我只在 Assembly 中递归地实现了“x 的幂”函数。

这是我目前所拥有的: http://pastebin.com/rsWALyCq(德语提示只要求输入 n 和 m)

感谢我在这方面能得到的每一点帮助。

--

所以我现在创建了 push/pop Statements Symetric,但仍然出现分段错误。我试图调试整个事情,并在第一个案例中放置了一个 Debug-Message。我编译了程序并用 n=0 和 m=0 进行了尝试,并且没有打印调试消息,所以他甚至没有进入第一种情况。我似乎无法弄清楚他为什么不这样做。

这是我目前的尝试: http://pastebin.com/D4jg7JGV

【问题讨论】:

    标签: assembly recursion x86 nasm ackermann


    【解决方案1】:

    解决方案:

    好的,我发现了问题:

    我没有正确管理 ebp 和 esp。所以,我现在在每个函数调用中都使用了 ENTER 和 LEAVE 宏,现在整个事情都正常工作了。 这是解决方案。感谢您的宝贵时间:

    asm_main:
        ENTER 0,0               ;setup Routine
        PUSHA
        MOV eax, prompt1        ;ask for n
    

    完整代码: http://pastebin.com/ZpPucpcs

    【讨论】:

    • ENTER 不是“宏”,而是(慢)机器指令。如果你想设置一个传统的帧指针,你应该push ebp / mov ebp, esp。这就是enter 0,0 所做的一切。
    【解决方案2】:

    如果您可以递归地执行此操作(伴随着所有随之而来的堆栈帧增长),那么这相当简单。基本思路,在子程序的代码中:

    ACKERMANN
    Get n and m off the stack or from registers
    Compare n to zero.
    If it is equal, jump to FIRSTCASE
    Compare m to zero
    If it is equal, jump to SECONDCASE
    put n + 1 into the first argument slot
    put m into the second argument slot
    call ACKERMANN
    put n into the first argument slot
    put the return of previous call into second argument slot
    call ACKERMANN
    put the return of the previous call into the return register/stack slot
    return
    
    FIRSTCASE
    put m+1 in the return register/stack slot
    return
    
    SECONDCASE
    Put n into the first argument slot
    put 1 into the second argument slot
    call ACKERMANN
    put the return of previous call into return register/stack slot
    return
    

    【讨论】:

    • 谢谢,我想这会对我有所帮助,现在我尝试翻译该结构。如果我完成了,我会回到这里发布完整的解决方案。
    • 我现在尝试将整个内容翻译成 Asm,但是在组装和编译之后,我遇到了分段错误,并且无法真正找到它发生的原因。即使我从 n=0 和 m=0 开始,所以他必须跳到第一个case。 pastebin.com/s6xh7kPc
    • 只浏览了您的代码,但我发现您的推送/弹出不是对称的。如果满足某个条件,您将在没有推送的情况下弹出,并且两次调用之间的推送次数多于弹出次数。
    猜你喜欢
    • 1970-01-01
    • 2013-10-13
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多