;****************************************************************************************
; Hauptprogramm. Im Moment wird hier das Unterprogarmm PrintWord getestet,		*
; indem alle Zweierpotenzen (die in ein Word passen) ausgegeben werden			*
;									    		*
; Dominik Jakob, 19.12.2002						    		*
;****************************************************************************************

data SEGMENT				
	
	out_wert DW ?			;Variablen die vom PrintWord gebraucht werden
	ausgabe DB '0$'			;
	divval DW ?			;

	CR_LF DB 10,13,"$"		;Variable die vom NewLine gebraucht wird

data ENDS


code SEGMENT	

	ASSUME CS:code, DS:data

start:			
	MOV AX, data			;
	MOV DS,AX			;DS muss ans richtige Ort pointen
	
	; TESTING STARTS HERE *********************************************************
	; DELETE AND WRITE YOUR CODE***************************************************
	MOV AX, 2			;in AX wird die auszugebende Zahl gespeichert
	MOV BX, 2			;AX immer mal 2 rechnen
	MOV CX, 15			;15 mal loopen

test_loop:
	MOV out_wert, AX		;Test PrintWord
	call PrintWord			;Unterprogrammaufruf
	call NewLine			;Unterprogrammaufruf

	MUL BX				;DX:AX = AX * Op  (Op ist hier im BX)

	LOOP test_loop			;
	; TESTING ENDS HERE************************************************************
	;******************************************************************************

end_prog:
	MOV AH, 4Ch			;System-Call setzten (end code)
	INT 21h				;Interrupt -> System-Call ausführen



;****************************************************************************************
; Unterprogramm zur Ausgabe von einer Word-Zahl auf den Bildschirm.			*
; Die Zahl muss sich in der Variable out_wert befinden!					*
;									    		*
; Dominik Jakob, 19.12.2002						    		*
;****************************************************************************************
PrintWord PROC NEAR			;Unterprogramm 	
			
	PUSH AX				;Register, die hier veraendert werden 
	PUSH BX				;auf Stack retten
	PUSH DX

	MOV divval, 10000
	MOV ausgabe, '0'

	;Falls die Zahl 0 ist einfach das Zeichen '0' ausgeben
	;------------------------------------------------------
	CMP out_wert, 0			;if value == 0
	JNE loop_1
	MOV DX, OFFSET ausgabe		;write '0'
	MOV AH, 9			;System-Call setzten (standard output)
	INT 21h				;Interrupt -> System-Call ausführen
	JMP return

	;Hier wird divval auf die Laenge der auszugenden Zahl gestutzt
	;-------------------------------------------------------------
loop_1:
	MOV DX, 0
	MOV AX, out_wert
	DIV divval			;AX := DX:AX / Op      DX:=Rest
	CMP AX, 0			
	JNE loop_2			;while(out_wert / divval == 0)

	MOV DX, 0	
	MOV AX, divval
	MOV BX, 10
	DIV BX				;AX := DX:AX / Op      DX:=Rest
	MOV divval, AX			;divval = divval / 10

	JMP loop_1

	;Ausgabe der Zahl
	;----------------
loop_2:					
	CMP divval, 1			;while(divval > 1)
	JBE weiter

	MOV DX, 0
	MOV AX, out_wert
	DIV divval			;AX := DX:AX / Op      DX:=Rest
	MOV out_wert, DX		;out_wert = out_wert mod divval 
					;(der Rest der Division in out_wert)
	ADD AL, 48		
	MOV ausgabe, AL
	MOV DX, OFFSET ausgabe		;write chr(out_wert / divval + 48)
	MOV AH, 9			;System-Call setzten (standard output)
	INT 21h				;Interrupt -> System-Call ausführen

	MOV DX, 0	
	MOV AX, divval
	MOV BX, 10
	DIV BX				;AX := DX:AX / Op      DX:=Rest
	MOV divval, AX			;divval = divval / 10

	JMP loop_2

weiter:
	MOV DX, 0			;das Ganze muss noch ein letztes Mal gemacht werden
	MOV AX, out_wert
	DIV divval			;AX := DX:AX / Op      DX:=Rest
	MOV out_wert, DX		;out_wert = out_wert mod divval 
					;(der Rest der Division in out_wert)
	ADD AL, 48		
	MOV ausgabe, AL
	MOV DX, OFFSET ausgabe		;write chr(out_wert / divval + 48)
	MOV AH, 9			;System-Call setzten (standard output)
	INT 21h				;Interrupt -> System-Call ausführen


return:		
	POP DX				;Register von Stack wiederherstellen
	POP BX
	POP AX

	ret				;Ruecksprung aus Unterprogramm

PrintWord ENDP				;Ende Unterprogramm



;****************************************************************************************
; Unterprogramm zur Ausgabe eines NEWLINE						*
; AX und DX werden gesichert!								*
;									    		*
; Dominik Jakob, 19.12.2002						    		*
;****************************************************************************************
NewLine PROC NEAR			;Unterprogramm 	
			
	PUSH DX				;DX auf Stack retten
	PUSH AX
	

	LEA DX, CR_LF			;Ausgabe Zeilenvorschub
	MOV AH, 9			;System-Call setzten (standard output)
	INT 21h				;Interrupt -> System-Call ausführen

	POP AX				;altes AX wiederherstellen
	POP DX				;altes DX wiederherstellen

	ret				;Ruecksprung aus Unterprogramm

NewLine ENDP				;Ende Unterprogramm

	

code ENDS
END start

