2013-12-19 22:22:57 +01:00

128 lines
2.2 KiB
NASM

.data
# Eingaben:
x: .long 2
n: .long 5
# Zu berechnen: x^n
intout:
.string "Ergebnis: %d\n"
.text
.globl main
main:
movl n, %ecx # Lade n in %ecx
cmp $0, %ecx # n = 0 ?
je .n_gleich_0
jmp .n_ungleich_0
# 1. Fall: n = 0 (Trivialfall):
##############################
.n_gleich_0:
############
movl $1, %eax # 1 in Ausgaberegister
jmp .end # zum ende springen
.n_ungleich_0:
and $0x00000001, %ecx # %ecx maskieren
cmp $1, %ecx # n ungerade?
je .n_ungerade # Jump -> n_ungerade
jmp .n_gerade # Jump -> n_gerade
# 2. Fall: n ist ungerade:
#########################
.n_ungerade:
###########
call .unterprogramm # Liefert Ergebnis von x^(n/2)^2 in %eax
movl x, %ebx
call .iteration # * x
jmp .end
# 3. Fall: n ist gerade:
########################
.n_gerade:
#########
call .unterprogramm # Liefert Ergebnis von x^(n/2)^2 in %eax
jmp .end
## Unterprogramm zur Berechnung von: x^(n/2)^2 ##
#################################################
.unterprogramm:
pushl %ebp # alten Basepointer sichern
movl n, %eax # n in %eax laden
shrl $1, %eax # %eax / 2
movl %eax, %ecx # %eax in %ecx verschieben
movl x, %eax # x in %eax laden
movl x, %ebx # x in %ebx laden
dec %ecx # n - 1
.loop_n:
cmp $0, %ecx # n = 0 ?
je .loop_n_end
call .iteration # Aufruf der Iteration
dec %ecx # n - 1
jmp .loop_n
.loop_n_end:
movl %eax, %ebx # %eax in %ebx zum Quadrieren
call .iteration # (x)^2
popl %ebp # alten Basepointer wiederherstellen
ret # zurück zum Aufrufer (n_gerade oder n_ungerade)
##############################################################################
#Unterprogramm Iteration
## ICH ÜBERGEB HIER IMMER NUR %eax ICH WEISS NICHT OB DIE MEHR SEHN WOLLEN; ABER WAS SOLL MAN NOCH ÜBERGEBEN?
## WENN ICH DIE AUSKOMMENTIERTEN TEILE WIEDER REINMACHE GEHT IRGENDWIE NIX MEHR BEI MIR
.iteration:
pushl %ebp # alten Basepointer sichern
#movl %esp, %ebx # neuen Basepointer erzeugen
mull %ebx
popl %ebp # alten Basepointer wiederherstellen
#movl %ebp, %esp # Stackpointer zurücksetzen (alternativ mit "leave")
ret # return
##########
# AUSGABE:
.end:
# Wert im %eax ausgeben
pushl %eax
pushl $intout
call printf
# Exit
movl $1, %eax
int $0x80