;Recursive Ackermann-Peter-Function in x86 nasm-assembly
;@AUTHOR: Alexander Schneider, Düsseldorf, Germany
;Ackermann-Peter-Function:
;A(n,m) = m + 1 if n == 0
;A(n,m) = A(n-1, 1) if n > 0 && m == 0
;A(n,m) = A(n-1, A(n, m-1)) if n > 0 && m > 0
;
;ecx is return the register
%include "asm_io.inc"
segment .data
prompt1 db "Bitte n (>=0) für die Ackermann-Berechnung eingeben: ",10,0
prompt2 db "Bitte m (>=0) für die Ackermann-Berechnung eingeben: ",10,0
prompt3 db "Das Ergebniss ist: ",0
promptError db "n und m müssen beide >= 0 sein",10,0
debug db "Debug-Message",10,0
segment .bss
segment .data
global asm_main
asm_main:
ENTER 0,0 ;setup Routine
PUSHA
MOV eax, prompt1 ;ask for n
CALL print_string
CALL read_int
CMP eax, 0 ;check n
JL inputError
MOV ebx, eax ;save n
MOV eax, prompt2 ;ask for m
CALL print_string
CALL read_int
CMP eax, 0 ;check m
JL inputError
MOV edx, eax ;save m
MOV ecx, 0
PUSH ebp
PUSH edx ;push m
PUSH ebx ;push n
CALL ackermann
POP ebx
POP edx
POP ebp
JMP result
ackermann:
MOV edx, [ebp+8] ;get m
MOV ebx, [ebp+12] ;get n
CMP ebx, 0
JE firstcase
CMP edx, 0
JE secondcase
;inner ackermann return for m
DEC edx
PUSH ebp
PUSH edx
PUSH ebx
CALL ackermann
POP ebx
POP edx
POP ebp
DEC ebx
PUSH ebp
PUSH edx ;return from last call is m
PUSH ebx
CALL ackermann
POP ebx
POP edx
POP ebp
RET
firstcase:
MOV eax, debug
CALL print_string
MOV ecx, edx
INC ecx
RET
secondcase:
DEC ebx
PUSH ebp
PUSH 1 ;push m
PUSH ebx ;push n
CALL ackermann
POP ebx
POP edx
POP ebp
RET
result:
MOV eax, prompt3
CALL print_string ;print result
MOV eax, ecx
CALL print_int
CALL print_nl
end:
POPA
MOV eax, 0 ;return Value for C-driver
LEAVE
RET
inputError: ;n or m was <0
MOV eax, promptError
CALL print_string
JMP end