;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 %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 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 PUSH ebp PUSH edx ;push m PUSH ebx ;push n CALL ackermann POP ebx POP edx POP ebp JMP end ackermann: MOV edx, [ebp+8] ;get m from stack MOV ebx, [ebp+12] ;get n from stack CMP ebx, 0 ;check if n is 0 JE firstcase CMP edx, 0 ;check if m is 0 JE secondcase DEC ebx PUSH ebp PUSH edx PUSH ebx CALL ackermann PUSH ebx PUSH eax CALL ackermann POP ebx POP edx POP ebp end: MOV ebx, eax ;save result MOV eax, prompt3 CALL print_string ;print result MOV eax, ebx CALL print_int CALL print_nl POPA MOV eax, 0 ;return Value for C-driver LEAVE RET firstcase: MOV eax, [ebp+8] ;Put m+1 in return Register INC eax ; RET ;return secondcase: MOV ebx, [ebp+12] ;get n DEC ebx ;n-1 MOV edx, dword 1 ;m= 1 PUSH ebp PUSH edx ;push new m PUSH ebx ;push new n CALL ackermann RET inputError: ;n or m was <0 MOV eax, promptError CALL print_string JMP end