#Aufgabe 8.3)
#Georg Kuschk

#ACHTUNG :	Da laut Forum davon ausgegangen werden soll, dass der Eingabewert,
#		falls er denn kleiner gleich 10 Stellen	besitzt,
#		mit maximal 32Bit darstellbar ist, wird nicht noch extra ueberprueft
#		ob der Eingabewert zwischen 4294967296 und 9999999999 liegt
#
#		Ebenso werden eventuell fuehrende Nullen nicht entfernt, sonder als
#		Dezimalstelle mitgezaehlt
#
#		Ausserdem koennen nur vorzeichenlose Dezimalzahlen eingegeben werden
#		(wie in Aufgabenstellung verlangt)
#
#
#		Belegung der globalen Variablen :
#		$s1	:	die Anzahl der auf dem Stack befindlichen Zahlen
#		$s2	:	Zeiger, der bei der Zeichenketten-Analyse diese durchlaeuft


.data
str_txt1:	.asciiz	"\nEingabe : "
str_txt2:	.asciiz "\nFehler! - Keine gueltige Eingabe !"
str_txt3:	.asciiz "\nProgrammende - letztes Rechenergebnis : "
str_txt4:	.asciiz "\nNoch keine Zahl auf den Stack geschrieben !"
str_txt5:	.asciiz "\nKeine 2 Operanden fuer die Operation auf dem Stack vorhanden !"
str_txt6:	.asciiz "\nKann Division durch Null nicht ausfuehren !"
str_txt7:	.asciiz "\nErgebnis der Operation : "
str_txt8:	.asciiz "\nWeniger als 2 Code-Worte auf dem Stack !"
str_txt9:	.asciiz "\nDistanz des Codes : "
str_txt10 :	.asciiz "-"
str_txt11 :	.asciiz "\n"
str_txt12:	.asciiz "\n2 gleiche Elemente auf dem Stack ! - keine Codeworte !"


str_input:	.space	256



.text


main:
	######################### Initialisierung der globalen Variablen ####################
	li	$s1,0		#in $s1 steht die Anzahl der auf dem Stack befindlichen Zahlen
	li	$s2,0		#$s2 zeigt auf den Anfang der aktuell zu bearbeitenden Komponente im String




	li	$v0,04		#print_string "Eingabe : "
	la	$a0,str_txt1
	syscall

	######################### Zeichenkette einlesen ###################################
	li	$v0,08		#read_string - EingabeString in str_input einlesen
	la	$a0,str_input	#Adresse des EingabeStrings laden
	li	$a1,256		#maximale Laenge des EingabeStrings
	syscall			#schliesslich die Funktion (read_string) aufrufen




loop_input:

	##### pruefen, ob das Ende der Zeichenkette erreicht wurde
	lb	$t1,str_input($s2)
	beq	$t1,10,exit_prog	#das Enter im String drin ?
	beq	$t1,0,exit_prog		#nullterminierter String ?



	######################### Zeichenkette komponentenweise auswerten ###################################

	##### Prüfen, ob 'q' eingegeben wurde #####
	li	$t1,0			#$t1 leeren
	add	$s0,$s2,1		#2.Zeichen auf Leerzeichen pruefen
	lb	$t1,str_input($s0)	#pruefen, ob die Komponente nur ein Zeichen enthaelt (2.Byte->Wert=32)
	bgt	$t1,32,check_number	#wenn nicht, dann muss sie entweder eine Zahl , k2/kb oder Fehler sein

	lb	$t1,str_input($s2)	#1. Zeichen der Zeichenkette in $t1 laden und auswerten
	bne	$t1,'q',check_distance	#wenn das Zeichen ungleich 'q' ist, dann als Nächstes
					#prüfen, ob das Zeichen ='h' ist

					#wenn Zeichen ='q' :
	add	$s2,$s2,2		#im String 2 Zeichen weiter nach rechts zur naechsten Komponente gehen
	li	$v0,04			#print_string "\nProgrammende - letztes Rechenergebnis : "
	la	$a0,str_txt3
	syscall

	bne	$s1,$zero,stack_print	#befinden sich auf dem Stack keine eingegebenen Zahlen
					#oder Rechenergebnisse so wird eine Meldung angezeigt,
					#ansonsten wird der letzte Wert vom Stack geholt und ausgegeben

	li	$v0,04			#print_string "Noch keine Zahl auf den Stack geschrieben !"
	la	$a0,str_txt4
	syscall
	j	exit_prog		#und zum Programm-Ende springen


	###Falls sich auf dem Stack Werte befand, so wird der "oberste" hier ausgegeben
stack_print:
	li	$v0,01			#print_int
	lw	$a0,4($sp)		#letzten Wert vom Stack holen
	addi	$sp,4			#Stackpointer aktualisieren
	syscall
	addi	$s1,-1			#Zahlen-Counter dekrementieren
	j	exit_prog		#und zum Programm-Ende springen











check_distance:
	##### Prüfen, ob 'h' eingegeben wurde #####
	bne	$t1,'h',check_symbol	#1. Zeichen der aktuellen Komponente befindet sich noch in $t1
					#wenn das Zeichen ungleich 'h' ist, dann als Nächstes
					#prüfen, ob ein Operationssymbol vorliegt

	add	$s2,$s2,2		#im String 2 Zeichen weiter nach rechts zur naechsten Komponente gehen

	blt	$s1,2,no_words		#ausserdem pruefen, ob mindestens zwei Worte auf dem Stack liegen

	####### An dieser Stelle ist die Eingabe 'h' ; also die Distanz des Codes berechnen #####
	#######	Die Codewoerter w1 und w2, deren Distanz zu berechnen ist, werden in t3 und t4 stehen

	#######	weitere Variablen :
	#######	$s1	:	die Anzahl der auf dem Stack befindlichen Zahlen
	####### $s3	:	gibt an, das wievielte Wort auf dem Stack gerade mit den anderen Woerten
	#######			"unter" ihm verglichen wird = Nr von w1
	####### $s4	:	gibt an, mit dem wievielten Wort auf dem Stack  $s3 gerade
	#######			verglichen wird = Nr von w2
	#######	$s5	:	minimalste Distanz zweier Codewoerter

	li	$s5,32
	li	$s3,1



dist_outer_loop:
	sll	$t5,$s3,2		#berechnen der Stack-Adresse des Codewortes w1 (zwischenspeichern in $t5)
	add	$sp,$sp,$t5		#Stackpointer zu w1 verschieben
	lw	$t3,($sp)		#Codewort w1 vom Stack lesen und in $t3 speichern
	sub	$sp,$sp,$t5		#Stackpointer wieder auf das erste Stack-Element zurueckverschieben

	add	$s4,$s3,1		#w2 liegt ein Wort tiefer im Stack

start_dist_inner_loop:
	sll	$t6,$s4,2		#berechnen der Stack-Adresse des Codewortes w2 (zwischenspeichern in $t6)
	add	$sp,$sp,$t6		#Stackpointer zu w2 verschieben
	lw	$t4,($sp)		#Codewort w2 vom Stack lesen und in $t4 speichern
	sub	$sp,$sp,$t6		#Stackpointer wieder auf das erste Stack-Element zurueckverschieben

	li	$t0,0			#$t0 gibt an, das wievielte Bit gerade verglichen wird
	li	$t1,1			#$t1 besitzt die Wertigkeit des gerade zu vergleichenden Bits (=2^$t0)
	li	$t2,0			#$t2 zaehlt die Distanz der beiden aktuellen Codewoerter


dist_inner_loop:
	and	$t5,$t3,$t1		#pruefen, ob das aktuelle Bit im 1.Codewort gesetzt ist
	and	$t6,$t4,$t1		#pruefen, ob das aktuelle Bit im 2.Codewort gesetzt ist

	beq	$t5,$t6,bit_equal	#pruefen, ob die beiden obigen Befehle das selbe Ergebnis lieferten
					#d.h. ob das aktuelle Bit in beiden Codewoertern gleich ist

	add	$t2,$t2,1		#wenn nicht, dann die Distanz um 1 erhoehen

bit_equal:
	beq	$t0,31,end_inner_loop	#wenn gerade das letzte (das 32.) Bit geprueft wurde, den Vergleich beenden

	add	$t0,$t0,1		#ansonsten den Bearbeitungs-Zeiger auf das naechsthoehere Bit verschieben
	sll	$t1,$t1,1		#naechste 2er-Potenz durch shift-left berechnen
	j	dist_inner_loop		#und die Schleife mit dem naechsten Bit neu durchlaufen

end_inner_loop:
	##### die Distanz der beiden Code-Woerter steht nun in $t2

	beq	$t2,$zero,no_code	#ist die Distanz 0 dann Fehler
	bge	$t2,$s5,no_min_dist	#ist die Distanz <= der bisherigen minimalen Distanz,
	add	$s5,$t2,0		#dann die soeben berechnete Distanz als die neue minimale Distanz setzen
no_min_dist:



	beq	$s4,$s1,w2_is_last	#pruefen, ob w2 das letzte Stack-Element ist
	add	$s4,$s4,1		#wenn nicht, dann ist w2 nun ein Wort tiefer im Stack
	j	start_dist_inner_loop	#und wieder die Distanz vom neuen w2 mit w1 bestimmen
w2_is_last:



	add	$s3,$s3,1
	sne	$t0,$s3,$s1		#pruefen, ob w1 das vorletzte Stack-Element ist
	sub	$s3,$s3,1

	beq	$t0,$zero,w1_is_last	#wenn ja, dann wurden alle noetigen n(n-1)/2 Vergleiche durchgefuehrt
					#und die maximale Distanz zwischen 2 Code-Woertern wurde bestimmt

	add	$s3,$s3,1		#wenn nicht, dann ist w1 nun ein Wort tiefer im Stack
	j	dist_outer_loop		#und wieder die Distanz vom neuen w1 mit allen
					#tiefer im Stack liegenden Code-Woertern bestimmen
w1_is_last:

	##### Distanz des Codes befindet sich nun in $s5
	##### Diese nun auf die Konsole ausgeben

	li	$v0,04			#print_string "\nDistanz des Codes : "
	la	$a0,str_txt9
	syscall

	li	$v0,01			#print_int (maximale Distanz zwischen 2 Code-Woertern)
	add	$a0,$s5,0
	syscall

	sll	$s1,$s1,2		#wie in der Aufgabenstellung gefordert, nun den Stack leeren
	add	$sp,$sp,$s1
	li	$s1,0			#Anzahl der eingegebenen Werte auf 0 setzen

	j	exit_prog		#und wieder neue Zeichenkette erfragen

no_words:
	li	$v0,04			#print_string "\nWeniger als 2 Code-Worte auf dem Stack !"
	la	$a0,str_txt8
	syscall
	j	exit_prog		#Programm beenden

no_code:
	li	$v0,04			#print_string "\n2 gleiche Elemente auf dem Stack ! - keine Codeworte !"
	la	$a0,str_txt12
	syscall
	j	exit_prog		#Programm beenden










check_symbol:
	##### Prüfen, ob ein Operationssymbol +,-,*,/ eingegeben wurde #####
	##### 1. Zeichen der aktuellen Komponente befindet sich noch in $t1					

	beq	$t1,'+',addition	# + -> springe zur Addition
	beq	$t1,'-',subtraction	# - -> springe zur Subtraktion
	beq	$t1,'*',multiplication	# * -> springe zur Multiplikation
	beq	$t1,'/',division	# / -> springe zur Division

	
	j	check_number		#wurde kein gueltiges Operationssymbol eingegeben, pruefen,
					#ob die Zeichenkette eine Zahl ist


addition:
	blt	$s1,2,no_ops		#Prüfen, ob mindestens zwei Operanden auf dem Stack liegen
	lw	$t0,8($sp)		#1.Operanden vom Stack holen
	lw	$t1,4($sp)		#2.Operanden vom Stack holen
	addi	$sp,8			#Stackpointer aktualisieren
	addi	$s1,-2			#Zahlen-Counter um die zwei soeben gelesenen Werte verringern
	add	$t0,$t0,$t1		#Addition ueber den zwei Operanden ausfuehren
	j	op_success		#Ergebnis berechnet
subtraction:
	blt	$s1,2,no_ops		#Prüfen, ob mindestens zwei Operanden auf dem Stack liegen
	lw	$t0,8($sp)		#1.Operanden vom Stack holen
	lw	$t1,4($sp)		#2.Operanden vom Stack holen
	addi	$sp,8			#Stackpointer aktualisieren
	addi	$s1,-2			#Zahlen-Counter um die zwei soeben gelesenen Werte verringern
	sub	$t0,$t0,$t1		#Subtraktion ueber den zwei Operanden ausfuehren
	j	op_success		#Ergebnis berechnet
multiplication:
	blt	$s1,2,no_ops		#Prüfen, ob mindestens zwei Operanden auf dem Stack liegen
	lw	$t0,8($sp)		#1.Operanden vom Stack holen
	lw	$t1,4($sp)		#2.Operanden vom Stack holen
	addi	$sp,8			#Stackpointer aktualisieren
	addi	$s1,-2			#Zahlen-Counter um die zwei soeben gelesenen Werte verringern
	mul	$t0,$t0,$t1		#Multiplikation ueber den zwei Operanden ausfuehren
	j	op_success		#Ergebnis berechnet
division:
	blt	$s1,2,no_ops		#Prüfen, ob mindestens zwei Operanden auf dem Stack liegen
	lw	$t0,8($sp)		#1.Operanden vom Stack holen
	lw	$t1,4($sp)		#2.Operanden vom Stack holen
	addi	$sp,8			#Stackpointer aktualisieren
	addi	$s1,-2			#Zahlen-Counter um die zwei soeben gelesenen Werte verringern

	beqz	$t1,divnull		#Division durch Null abfangen
	div	$t0,$t0,$t1		#wenn Divisor ungleich Null, dann Ergebnis berechnen
	j	op_success		#Ergebnis berechnet
divnull:				#Division durch Null anzeigen
	li	$v0,04			#print_string "\nKann Division durch Null nicht ausfuehren !"
	la	$a0,str_txt6
	syscall
	j	exit_prog		#bei Division durch Null gleich wieder neue Zeichenkette erfragen



op_success:
	###bei erfolgreich ausgefuehrter Operation das Ergebnis (liegt in $t0) auf den Stack schreiben
	addi	$sp,-4			#Stackpointer dekrementieren
	sw	$t0,4($sp)		#Ergebnis auf den Stack schreiben
	add	$s1,$s1,1		#Zahlen-Counter inkrementieren

	add	$s2,$s2,2		#im String 2 Zeichen weiter nach rechts zur naechsten Komponente gehen

#	###und auch noch auf der Konsole ausgeben
#	li	$v0,04			#print_string "\nErgebnis der Operation : "
#	la	$a0,str_txt7
#	syscall
#	li	$v0,01			#print_int
#	add	$a0,$t0,0		#Ergebnis der letzten Rechnung der Funktion als Argument uebergeben
#	syscall
	j	loop_input		#und wieder neue Zeichenkette erfragen

no_ops:
	li	$v0,04			#print_string "\nKeine 2 Operanden fuer die Operation auf dem Stack vorhanden !"
	la	$a0,str_txt5
	syscall
	j	exit_prog		#und wieder neue Zeichenkette erfragen











check_number:
	##### Prüfen, ob die Eingabe eine gueltige, vorzeichenlose Dezimalzahl ist #####
	li	$s0,0			#$s0 zaehlt die Anzahl der Ziffern
	add	$t3,$s2,0		#$t3 zeigt auf das aktuelle Zeichen im String

input_evaluation:
	lb	$t1,str_input($t3)	#Zeichen der Komponente einzeln in $t1 laden und auswerten

	beq	$t1,10,input_end	#Ende der String-Komponente erreicht?
	beq	$t1,32,input_end	#Ende der String-Komponente erreicht?

	blt	$t1,'0',check_k2kb	#wenn nicht : ist das Zeichen eine Ziffer ('0'-'9')?
	bgt	$t1,'9',check_k2kb

	add	$s0,$s0,1		#Zeichen ist eine Ziffer -> Anzahl der Ziffern inkrementieren
					#und den Integer-Wert der Ziffer auf den Stack schreiben
	add	$t3,$t3,1		#und auch in der String-Komponente ein Zeichen weiter nach rechts


	addi	$sp,-1			#Stackpointer dekrementieren
	sub	$t1,$t1,'0'		#das gelesene Zeichen in entsprechende Ziffer umrechnen
	sb	$t1,1($sp)		#und die Ziffer auf den Stack schreiben

	j	input_evaluation	#da das Ende des Eingabestrings noch nicht erreicht ist,
					#das naechste Zeichen auswerten

input_end:
	beq	$s0,$zero,input_error	#hat die Zahl 0 Stellen ? -> dann Fehler
	bgt	$s0,10,input_error	#hat die Zahl > 10 Stellen ? -> dann Fehler

	##### EingabeString wurde jetzt akzeptiert -> Binaerzahl berechnen
	##### zur Erinnerung : Anzahl der Ziffern der Dezimalzahl steht in $s0 und muss an dieser Stelle >0 sein
	##### und die Ziffern stehen in umgekehrter Reihenfolge auf dem Stack

	add	$s2,$s2,$s0		#im String 'Anzahl der Ziffern' Zeichen weiter nach rechts zur naechsten Komponente gehen

	lb	$t1,str_input($s2)	#falls auf die Zahl ein Leerzeichen folgt, in der String-Komponente noch ein Zeichen weiter nach rechts
	bne	$t1,32,no_space
	add	$s2,$s2,1
no_space:


	li	$t0,0			#das Gesamtergebnis wird zunaechst in $t0 zwischengespeichert
	li	$t1,1			#in $t1 stehen die gerade benoetigten 10er-Potenzen
dec2bin_loop:
	li	$t2,0			#$t2 fuer Aufnahme eines Bytes vorbereiten
	lb	$t2,1($sp)		#Ziffer vom Stack holen
	addi	$sp,1			#Stackpointer aktualisieren

	mul	$t2,$t2,$t1		#Ziffern-Wertigkeit entsprechend der Dezimal-Stelle berechnen
	add	$t0,$t0,$t2		#und zum Gesamtergebnis hinzuaddieren

	mul	$t1,$t1,10		#naechste 10er-Potenz berechnen
	sub	$s0,$s0,1		#Anzahl der noch abzuarbeitenden Stellen dekrementieren
	bgt	$s0,$zero,dec2bin_loop	#und wenn diese >0 ist, mit dem Verfahren fortfahren


	##### Die bisher von dem Programm-Teil "check_number" auf den Stack geschriebenen Ziffern wieder entfernen
	add	$sp,$sp,$s0		#Stackpointer wieder um die Anzahl der auf den Stack geschriebenen
					#Bytes erhoehen

	##### Alle Ziffern wurden abgearbeitet , die Zahl ist erkannt und steht nun in $t0 -> Zahl auf den Stack schreiben
	addi	$sp,-4			#Stackpointer dekrementieren
	sw	$t0,4($sp)		#Zahl auf den Stack schreiben
	add	$s1,$s1,1		#Zahlen-Counter inkrementieren


	j	loop_input		#und wieder neue Zeichenkette erfragen






#####################################################################################################################
check_k2kb:
	add	$t2,$s2,0		#$t2 zeigt jetzt auf den Anfang der String-Komponente
	lb	$t1,str_input($t2)	#Zeichen des eingegebenen Strings einzeln in $t1 laden und auswerten
	bne	$t1,'k',input_error	#Eingabestring auf 'k2' bzw. 'kb' pruefen
	add	$t2,$t2,1
	lb	$t1,str_input($t2)
	beq	$t1,'2',function_k2	#wenn String='k2' dann als Zweierkomplement interpretieren
	beq	$t1,'b',function_kb	#wenn String='kb' dann als normal Binärzahl interpretieren
	j	input_error		#wenn die Zeichenkette auch nicht k2 oder kb ist, dann ungueltige Eingabe






function_k2:
	add	$t2,$t2,1
	lb	$t1,str_input($t2)
	bgt	$t1,32,input_error	#noch pruefen, ob nach 'k2' ein Leerzeichen oder Enter folgt

	add	$s2,$s2,3		#im String 3 Zeichen weiter nach rechts zur naechsten Komponente gehen

	beq	$s1,$zero,stack_empty	#Prüfen, ob ueberhaupt eine Zahl auf dem Stack liegt
	lw	$a0,4($sp)		#obersten Wert vom Stack holen und in Argument-Register schreiben
	jal	out_k2			#Funktion aufrufen
	li	$v0,04			#noch den geforderten Zeilenvorschub auf die Konsole schreiben
	la	$a0,str_txt11
	syscall
	j	loop_input		#und wieder neue Zeichenkette erfragen



function_kb:
	add	$t2,$t2,1
	lb	$t1,str_input($t2)
	bgt	$t1,32,input_error	#noch pruefen, ob nach 'kb' ein Leerzeichen oder Enter folgt

	add	$s2,$s2,3		#im String 3 Zeichen weiter nach rechts zur naechsten Komponente gehen

	beq	$s1,$zero,stack_empty	#Prüfen, ob ueberhaupt eine Zahl auf dem Stack liegt
	lw	$a0,4($sp)		#obersten Wert vom Stack holen und in Argument-Register schreiben
	jal	out_bin			#Funktion aufrufen
	li	$v0,04			#noch den geforderten Zeilenvorschub auf die Konsole schreiben
	la	$a0,str_txt11
	syscall
	j	loop_input		#und wieder neue Zeichenkette erfragen


stack_empty:
	li	$v0,04			#print_string "\nNoch keine Zahl auf den Stack geschrieben !"
	la	$a0,str_txt4
	syscall
	j	loop_input		#und wieder neue Zeichenkette erfragen

#####################################################################################################################








##### Hier ist das Sprungziel des Programms fuer eine ungueltige Eingabe
input_error:

	li	$v0,04		#print_string "\nFehler! - Keine gueltige Eingabe !"
	la	$a0,str_txt2
	syscall

	##### Die bisher von dem Programm-Teil "check_number" auf den Stack geschriebenen Ziffern wieder entfernen
	add	$sp,$sp,$s0		#Stackpointer wieder um die Anzahl der auf den Stack geschriebenen
					#Bytes erhoehen

	j	exit_prog		#und wieder neue Zeichenkette erfragen






































####################################################################################################################
#Aufgabe 7.3)

####################################################################################################################
	###### Interpretiere $a0 als vorzeichenlose Zahl - Ausgabe als Dezimalzahl (ohne fuehrende Nullen)
out_dez:
	move	$t0,$sp			#Stackpointer in $t0 retten

	li	$t1,0			#Indikator um fuehrende Nullen zu entfernen
	li	$t2,1000000000		#hoechste 10er Potenz die in einer 32Bit Zahl auftreten kann (1 Mrd)

loop_out_dez:
	div	$t3,$a0,$t2		#Zahl durch die aktuelle 10er Potenz dividieren


	sne	$t4,$t3,$zero		#ist die Ziffer ungleich Null, dann setze $t4 auf 1
	or	$t1,$t1,$t4		#OR Verknuepfung mit dem Indikator fuer fuehrende Nullen
					#zeigt an, ob schon einmal eine Ziffern ungleich Null ausgegeben wurde

	seq	$t4,$t2,1		#wird allerdings gerade die niedrigste 10er Potenz abgearbeitet,
	or	$t1,$t1,$t4		#dann wird Ausgabe der Ziffer erzwungen

	###### Ausgabe der Ziffer, falls $t1 ungleich Null
	beq	$t1,$zero,leading_zero	#fuehrende Nullen nicht ausgeben


	li	$v0,01			#print_int
	add	$t4,$a0,0		#$a0 = auszugebende Zahl in $t4 zwischenspeichern
	add	$a0,$t3,0		#10er Stelle laden
	syscall				#Ziffer ausgeben
	add	$a0,$t4,0		#zwischengespeicherte Zahl wieder nach $a0 schreiben

	beq	$t2,1,exit_out_dez	#wenn die niedrigste 10er Potenz abgearbeitet wurde, Funktion beenden

leading_zero:
	rem	$a0,$a0,$t2		#die restliche auszugebende Zahl ist "Zahl modulo aktueller 10er-Potenz"
	div	$t2,$t2,10		#eine 10er Potenz tiefer gehen
	j	loop_out_dez
exit_out_dez:
	move	$sp,$t0			#Stackpointer restaurieren
	jr	$ra			#return to caller
####################################################################################################################










####################################################################################################################
	###### Interpretiere $a0 als Einerkomplement
	###### Ausgabe als vorzeichenbehaftete Dezimalzahl (ohne fuehrende Nullen)
out_k1:
	move	$t0,$sp			#Stackpointer in $t0 retten

	##### Prüfen, ob die Zahl negativ ist
	srl	$t1,$a0,31		#dazu feststellen, ob das 31. Bit gesetzt ist
	beq	$t1,$zero,positiv_k1	#wenn nicht, als positive Zahl behandeln

	##### Falls die Zahl negativ ist, zuerst ein "-" ausgeben :
	li	$v0,04			#print_string "-"
	move	$t2,$a0			#$a0 in $t4 retten
	la	$a0,str_txt1
	syscall
	move	$a0,$t2			#$a0 restaurieren

	##### Dann die Zahl invertieren -> dies ergibt die entsprechende positive Zahl (den Betrag also)
	xor	$a0,$a0,4294967295	#die Zahl invertieren (  $a0 XOR ((2^32)-1)  )
	##### und mit der Ausgabe des Betrages fortfahren :

positiv_k1:
	li	$t1,0			#Indikator um fuehrende Nullen zu entfernen
	li	$t2,1000000000		#hoechste 10er Potenz die in einer 32Bit Zahl auftreten kann (1 Mrd)

loop_out_k1:
	div	$t3,$a0,$t2		#Zahl durch die aktuelle 10er Potenz dividieren


	sne	$t4,$t3,$zero		#ist die Ziffer ungleich Null, dann setze $t4 auf 1
	or	$t1,$t1,$t4		#OR Verknuepfung mit dem Indikator fuer fuehrende Nullen
					#zeigt an, ob schon einmal eine Ziffern ungleich Null ausgegeben wurde

	seq	$t4,$t2,1		#wird allerdings gerade die niedrigste 10er Potenz abgearbeitet,
	or	$t1,$t1,$t4		#dann wird Ausgabe der Ziffer erzwungen

	###### Ausgabe der Ziffer, falls $t1 ungleich Null
	beq	$t1,$zero,leading_zero_k1	#fuehrende Nullen nicht ausgeben


	li	$v0,01			#print_int
	add	$t4,$a0,0		#$a0 = auszugebende Zahl in $t4 zwischenspeichern
	add	$a0,$t3,0		#10er Stelle laden
	syscall				#Ziffer ausgeben
	add	$a0,$t4,0		#zwischengespeicherte Zahl wieder nach $a0 schreiben

	beq	$t2,1,exit_out_k1	#wenn die niedrigste 10er Potenz abgearbeitet wurde, Funktion beenden

leading_zero_k1:
	rem	$a0,$a0,$t2		#die restliche auszugebende Zahl ist "Zahl modulo aktueller 10er-Potenz"
	div	$t2,$t2,10		#eine 10er Potenz tiefer gehen
	j	loop_out_k1
exit_out_k1:
	move	$sp,$t0			#Stackpointer restaurieren
	jr	$ra			#return to caller
####################################################################################################################










####################################################################################################################
	###### Interpretiere $a0 als Zweierkomplement
	###### Ausgabe als vorzeichenbehaftete Dezimalzahl (ohne fuehrende Nullen)
out_k2:
	move	$t0,$sp			#Stackpointer in $t0 retten

	##### Prüfen, ob die Zahl negativ ist
	srl	$t1,$a0,31		#dazu feststellen, ob das 31. Bit gesetzt ist
	beq	$t1,$zero,positiv_k2	#wenn nicht, als positive Zahl behandeln

	##### Falls die Zahl negativ ist, zuerst ein "-" ausgeben :
	li	$v0,04			#print_string "-"
	move	$t2,$a0			#$a0 in $t4 retten
	la	$a0,str_txt1
	syscall
	move	$a0,$t2			#$a0 restaurieren

	##### Dann eine 1 subtrahieren und das Ergebnis invertieren
	##### -> dies ergibt die entsprechende positive Zahl (den Betrag also)
	sub	$a0,$a0,1
	xor	$a0,$a0,4294967295	#die Zahl invertieren (  $a0 XOR ((2^32)-1)  )
	##### und mit der Ausgabe des Betrages fortfahren :

positiv_k2:
	li	$t1,0			#Indikator um fuehrende Nullen zu entfernen
	li	$t2,1000000000		#hoechste 10er Potenz die in einer 32Bit Zahl auftreten kann (1 Mrd)

loop_out_k2:
	div	$t3,$a0,$t2		#Zahl durch die aktuelle 10er Potenz dividieren


	sne	$t4,$t3,$zero		#ist die Ziffer ungleich Null, dann setze $t4 auf 1
	or	$t1,$t1,$t4		#OR Verknuepfung mit dem Indikator fuer fuehrende Nullen
					#zeigt an, ob schon einmal eine Ziffern ungleich Null ausgegeben wurde

	seq	$t4,$t2,1		#wird allerdings gerade die niedrigste 10er Potenz abgearbeitet,
	or	$t1,$t1,$t4		#dann wird Ausgabe der Ziffer erzwungen

	###### Ausgabe der Ziffer, falls $t1 ungleich Null
	beq	$t1,$zero,leading_zero_k2	#fuehrende Nullen nicht ausgeben


	li	$v0,01			#print_int
	add	$t4,$a0,0		#$a0 = auszugebende Zahl in $t4 zwischenspeichern
	add	$a0,$t3,0		#10er Stelle laden
	syscall				#Ziffer ausgeben
	add	$a0,$t4,0		#zwischengespeicherte Zahl wieder nach $a0 schreiben

	beq	$t2,1,exit_out_k2	#wenn die niedrigste 10er Potenz abgearbeitet wurde, Funktion beenden

leading_zero_k2:
	rem	$a0,$a0,$t2		#die restliche auszugebende Zahl ist "Zahl modulo aktueller 10er-Potenz"
	div	$t2,$t2,10		#eine 10er Potenz tiefer gehen
	j	loop_out_k2
exit_out_k2:
	move	$sp,$t0			#Stackpointer restaurieren
	jr	$ra			#return to caller
####################################################################################################################













####################################################################################################################
	###### $a0 als Binärzahl-Zeichenkette ausgeben (mit fuehrenden Nullen)
	###### Anmerkung : die Code-Zeilen, welche die fuehrenden Nullen streichen, wurden auskommentiert
out_bin:
	move	$t0,$sp			#Stackpointer in $t0 retten

#	li	$t1,0			#Indikator um fuehrende Nullen zu entfernen
	li	$t2,31			#zu bearbeitende 2er Potenz initialisieren (=maximale 2er Potenz)

loop_out_bin:

	srl	$t3,$a0,$t2		#Zahl durch die aktuelle 2er Potenz dividieren

#	sne	$t4,$t3,$zero		#ist das Bit ungleich Null, dann setze $t4 auf 1
#	or	$t1,$t1,$t4		#OR Verknuepfung mit dem Indikator fuer fuehrende Nullen
#					#zeigt an, ob schon einmal ein Bit ungleich Null ausgegeben wurde
#
#	seq	$t4,$t2,0		#wird allerdings gerade 2^0 abgearbeitet,
#	or	$t1,$t1,$t4		#dann wird Ausgabe des Bits erzwungen
#
#	###### Ausgabe der Ziffer, falls $t1 ungleich Null
#	beq	$t1,$zero,leading_zero_bin	#fuehrende Nullen nicht ausgeben


	li	$v0,01			#print_int
	add	$t4,$a0,0		#$a0 = auszugebende Zahl in $t4 zwischenspeichern
	add	$a0,$t3,0		#aktuell auszugebendes Bit laden
	syscall				#Bit ausgeben
	add	$a0,$t4,0		#zwischengespeicherte Zahl wieder nach $a0 schreiben

	beq	$t2,0,exit_out_bin	#wenn 2^0 abgearbeitet wurde, Funktion beenden

#leading_zero_bin:
	li	$t4,1
	sll	$t4,$t4,$t2
	rem	$a0,$a0,$t4		#die restliche auszugebende Zahl ist "Zahl modulo aktueller 2er-Potenz"


	sub	$t2,$t2,1		#eine 2er Potenz tiefer gehen
	j	loop_out_bin
exit_out_bin:
	move	$sp,$t0			#Stackpointer restaurieren
	jr	$ra			#return to caller
####################################################################################################################































exit_prog:

#	##### auf Tastendruck zum Beenden warten #####
#	li	$v0,05		#read_int
#	syscall


	li	$v0,10		#exit
	syscall


