82 lines
2.1 KiB
NASM
82 lines
2.1 KiB
NASM
.data
|
|
|
|
# Eingaben:
|
|
x: .long 2
|
|
n: .long 7
|
|
|
|
# Zu berechnen: x^n
|
|
|
|
intout: .string "Ergebnis: %d\n"
|
|
|
|
.text
|
|
######################################################################
|
|
.globl _main
|
|
.global _mainCRTStartup # debugging 4 msvs/windows
|
|
######################################################################
|
|
_mainCRTStartup: # do nothing
|
|
jmp _main # jump to _main
|
|
######################################################################
|
|
_main:
|
|
|
|
movl $1, %eax # Lade 1 in %eax
|
|
movl x, %ebx # Lade x in %ebx
|
|
movl n, %ecx # Lade n in %ecx
|
|
|
|
call .x_hoch_n_recursiv # call subrutine x_hoch_n_recursiv
|
|
|
|
jmp .end # finish
|
|
|
|
######################################################################
|
|
;# %eax = current result
|
|
;# %ebx = x
|
|
;# %ecx = n
|
|
.x_hoch_n_recursiv:
|
|
|
|
cmp $0, %ecx # n = 0 ?
|
|
je .x_hoch_n_recursiv_ancor
|
|
|
|
movl $0b000001, %edx # %edx = 1b
|
|
and %ecx, %edx # %edx = 1b if n = even else 0b if n = uneven
|
|
|
|
cmp $0, %edx # n even?
|
|
je .x_hoch_n_recursiv_even # jump to even
|
|
jmp .x_hoch_n_recursiv_uneven # else jump to uneven
|
|
|
|
.x_hoch_n_recursiv_even:
|
|
|
|
push %ebx # save x; nur temporär
|
|
xchg %eax, %ecx # exchange a(result) & c(n)
|
|
movl $2, %ebx # %edx = 2
|
|
cdq # clear %edx
|
|
idivl %ebx # n /= 2
|
|
xchg %eax, %ecx # exchange a & c back
|
|
pop %ebx # restore x
|
|
call .x_hoch_n_recursiv # calculate x ^ (n/2)
|
|
cdq # clear %edx
|
|
imull %eax, %eax # calculate (x ^ (n/2)) ^ (2)
|
|
|
|
ret # outa here
|
|
|
|
.x_hoch_n_recursiv_uneven: #ACHTUNG: BENUTZT x_hoch_n_recursiv_even -> AUFGABENSTELLUNG?!
|
|
|
|
decl %ecx # n -= 1
|
|
call .x_hoch_n_recursiv # calculate the rest (x^((n-1)/2)) ^(2)
|
|
|
|
imull %ebx, %eax # ((x^((n-1)/2)) ^(2)) * x
|
|
ret # outa here
|
|
|
|
.x_hoch_n_recursiv_ancor: # ancor-marker
|
|
movl $1, %eax # result = 1
|
|
ret # jump out
|
|
|
|
######################################################################
|
|
.end:
|
|
# Wert im %eax ausgeben
|
|
pushl %eax
|
|
pushl $intout
|
|
call _printf
|
|
|
|
|
|
# Exit
|
|
movl $1, %eax
|
|
#int $0x80 |