程序集x86:我必须编写Ackermann函数

时间:2012-03-14 00:56:02

标签: assembly x86

我需要编程Ackermann功能。这就是我到目前为止所做的:

    .model small
;
    extrn   putstrng:far
    extrn   newline:far
    extrn   getdec$:far
    extrn   putdec$:far
; 
;
    .stack 1024                  
;
    .const


    .data

    .code
    assume ds:dgroup
;
debut:  mov     ax, seg dgroup     
    mov     ds, ax
    mov     es, ax
;

    mov     ax,2   ; value of N
    mov     bx,ax
    mov     ax,2 ; Value of M
    mov     dx,ax
    mov     cx,0

    push    dx
    push    bx

    call ackermann

    pop     bx
    pop     dx

    MOV ax, 0
    MOV ax, cx
call    putdec$
call    newline


    mov     ax, 4c00h          
    int     21h

ackermann   proc far C uses cx

    mov dx, [bp+6] 
    mov bx, [bp+4]
    cmp bx, 0
    JE firstCase
    cmp dx, 0
    JE secondCase
    dec dx
    push dx
    push bx
    CALL ackermann
    pop bx
    pop dx
    dec bx
    push dx
    push bx
    CALL ackermann
    pop bx
    pop dx
    ret


firstCase:
    MOV cx, dx
    inc cx
    ret


secondCase:
    DEC bx
    push dx
    push bx
    call ackermann
    pop bx
    pop dx
    ret

ackermann endp

    end     debut

无论我为N或M的价值做什么,我总能得到答案0.我想我知道为什么。这部分:

MOV ax, 0
MOV ax, cx
call    putdec$
call    newline

可能是错的,但我不知道如何处理它。

非常感谢任何帮助。

感谢。

1 个答案:

答案 0 :(得分:5)

假设您的Ackermann函数实际正常工作并将其结果保留在cx寄存器中,并且putdec$打印ax寄存器中的值,那么你所展示的代码段绝对没有错。

首先将{0}首先加载到ax,然后将其替换为cx

因此,你的问题在于:

  • putdec$无法打印ax
  • 您的Ackermann功能无法正常工作。
  • 您的Ackermann函数未在cx中返回其值。

Fist步骤是启动调试器并在mov ax, 0指令处设置断点 - 这将告诉您cx(以及其他寄存器)中的值,以检查Ackermann功能是否正常工作

然后你可能需要返回并单步执行该功能,将它与你期望在每个阶段用纸和铅笔进行比较。


通过一些静态代码分析,以及对Ackermann函数实际意图做什么的快速调查:-),我可以看出以下内容:

我不确定你有没有一件事(如果你使用维基百科定义的Ackermann函数here)是第二种情况。它声明:

         /  n + 1             if m = 0
A(m,n) = |  A(m-1,1)          if m > 0 and n = 0
         \  A(m-1,A(m,n-1))   if m > 0 and n > 0

您的第二个案例代码按预期递减bx/m但仅留下dx/n,而不是将其设置为一个。

在你的第三种情况下(虽然我没有仔细查看过)你确实两次调用该函数但是现在我可以看到cx的转移,即第一次内部A()调用的结果,将任何一个寄存器压入堆栈以进行外部调用。这是计算A(x,A(y,z))等嵌套函数的重要步骤。

相反,您的外部调用似乎使用原始值的某些变体。

这两个有用的指针应该是一个良好的开端,磨练你的调试技巧并成为一个更好的开发人员: - )