;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