I need to program the Ackermann function. This is what I have so far:
.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
Whatever I put for the value of N or M, i always get the answer 0. I think I know why. This part :
MOV ax, 0
MOV ax, cx
call putdec$
call newline
is probably wrong, but I don’t know what to do with it.
Any help will be greatly appreciated.
Thanks.
Assuming that your Ackermann function actually works and leaves its result in the
cxregister, and thatputdec$prints the value in theaxregister, there’s absolutely nothing wrong with that code segment you’ve shown.It needlessly loads zero into
axfirst but then replaces it withcx.Hence your problem lies with one of:
putdec$does not printax.cx.Fist step is to fire up your debugger and set a breakpoint at the
mov ax, 0instruction – this will tell you what value is incx(and other registers) to check whether the Ackermann function is working.Then you may need to go back and single-step through the function, comparing it to what you expect to happen at each stage with some paper and pencils.
With a bit of static code analysis, and a quick investigation into what this Ackermann function actually is meant to do 🙂 , I can discern the following:
One thing I’m not sure you have right (if you’re using the Wikipedia definition of the Ackermann function here) is the second case. It states that:
Your second case code decrements
bx/mas expected but leavesdx/nalone, rather than setting it to one.In your third case (though I haven’t looked closely) you do call the function twice but nowehere can I see a transfer of
cx, the result of the first, innerA()call, to either one of the registers pushed onto the stack for the outer call. This would be a vital step in calculating a nested function likeA(x,A(y,z)).Instead, your outer call seems to use some variation of the original values.
Those two helpful pointers should be a good start for you, to hone your debugging skills and become a better developer 🙂