program UnitDemo {
	section object {
		MathLib, StringUtils
	}
	section module {
 		io,
		std
	}
	section data {
		int rax = 0
		int rbx = 0
		int rcx = 0
		int rdx = 0
		int rsi = 0
		int rdi = 0
		int r8 = 0
		int r9 = 0
		int r10 = 0
		ptr arg0 = null
		string str_0 = "  MXVM Unit Demo  "
		string str_1 = "Test return"
		string str_2 = "Arithmetic"
		string str_3 = "a"
		string str_4 = "b"
		string str_5 = "Add(a, b)"
		string str_6 = "Subtract(a, b)"
		string str_7 = "Multiply(a, b)"
		string str_8 = "Divide(a, b)"
		string str_9 = "Power & Factorial"
		string str_10 = "2^10"
		string str_11 = "3^5"
		string str_12 = "Factorial"
		string str_13 = "Min / Max / Abs"
		string str_14 = "Max(100, 200)"
		string str_15 = "Min(100, 200)"
		string str_16 = "Abs(-55)"
		string str_17 = "Abs(55)"
		string str_18 = "Edge Cases"
		string str_19 = "Divide(10, 0)"
		string str_20 = "Factorial(0)"
		string str_21 = "Power(5, 0)"
		string str_22 = "  Demo Complete  "
		string fmt_int = "%lld "
		string fmt_str = "%s "
		string newline = "\n"
		int a = 0
		int b = 0
		int i = 0
	}
	section code {
	start:
		call MathLib.PROC_UNIT_INIT
		call StringUtils.PROC_UNIT_INIT
		mov StringUtils.arg0, str_0
		mov StringUtils.rbx, 20
		call StringUtils.PROC_PrintBanner
		print newline
		call MathLib.FUNC_TestReturn
		mov rbx, MathLib.rax
		mov i, rbx
		print fmt_str, str_1
		print fmt_int, i
		print newline
		push rbx
		mov StringUtils.arg0, str_2
		call StringUtils.PROC_PrintHeader
		pop rbx
		mov a, 42
		mov b, 17
		push rbx
		mov StringUtils.arg0, str_3
		mov StringUtils.rbx, a
		call StringUtils.PROC_PrintLabeledInt
		pop rbx
		push rbx
		mov StringUtils.arg0, str_4
		mov StringUtils.rbx, b
		call StringUtils.PROC_PrintLabeledInt
		pop rbx
		push rbx
		mov MathLib.rbx, a
		mov MathLib.rcx, b
		call MathLib.FUNC_Add
		pop rbx
		mov rcx, MathLib.rax
		push rbx
		mov StringUtils.arg0, str_5
		mov StringUtils.rbx, rcx
		call StringUtils.PROC_PrintLabeledInt
		pop rbx
		push rbx
		push rcx
		mov MathLib.rbx, a
		mov MathLib.rcx, b
		call MathLib.FUNC_Subtract
		pop rcx
		pop rbx
		mov rdx, MathLib.rax
		push rbx
		push rcx
		mov StringUtils.arg0, str_6
		mov StringUtils.rbx, rdx
		call StringUtils.PROC_PrintLabeledInt
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		mov MathLib.rbx, a
		mov MathLib.rcx, b
		call MathLib.FUNC_Multiply
		pop rdx
		pop rcx
		pop rbx
		mov rsi, MathLib.rax
		push rbx
		push rcx
		push rdx
		mov StringUtils.arg0, str_7
		mov StringUtils.rbx, rsi
		call StringUtils.PROC_PrintLabeledInt
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		mov MathLib.rbx, a
		mov MathLib.rcx, b
		call MathLib.FUNC_Divide
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov rdi, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		mov StringUtils.arg0, str_8
		mov StringUtils.rbx, rdi
		call StringUtils.PROC_PrintLabeledInt
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		call StringUtils.PROC_PrintSeparator
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		print newline
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		mov StringUtils.arg0, str_9
		call StringUtils.PROC_PrintHeader
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		mov MathLib.rbx, 2
		mov MathLib.rcx, 10
		call MathLib.FUNC_Power
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r8, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		mov StringUtils.arg0, str_10
		mov StringUtils.rbx, r8
		call StringUtils.PROC_PrintLabeledInt
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 3
		mov MathLib.rcx, 5
		call MathLib.FUNC_Power
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_11
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov i, 1
	FOR_0:
		cmp i, 10
		jg ENDFOR_1
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, i
		call MathLib.FUNC_Factorial
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_12
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
	FOR_CONTINUE_2:
		add i, 1
		jmp FOR_0
	ENDFOR_1:
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		call StringUtils.PROC_PrintSeparator
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		print newline
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_13
		call StringUtils.PROC_PrintHeader
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 100
		mov MathLib.rcx, 200
		call MathLib.FUNC_Max
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_14
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 100
		mov MathLib.rcx, 200
		call MathLib.FUNC_Min
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_15
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, 0
		sub r9, 55
		invoke abs, r9
		return r10
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_16
		mov StringUtils.rbx, r10
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r10, 55
		invoke abs, r10
		return r9
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_17
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		call StringUtils.PROC_PrintSeparator
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		print newline
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_18
		call StringUtils.PROC_PrintHeader
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 10
		mov MathLib.rcx, 0
		call MathLib.FUNC_Divide
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_19
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 0
		call MathLib.FUNC_Factorial
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_20
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov MathLib.rbx, 5
		mov MathLib.rcx, 0
		call MathLib.FUNC_Power
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		mov r9, MathLib.rax
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_21
		mov StringUtils.rbx, r9
		call StringUtils.PROC_PrintLabeledInt
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		call StringUtils.PROC_PrintSeparator
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		print newline
		push rbx
		push rcx
		push rdx
		push rsi
		push rdi
		push r8
		mov StringUtils.arg0, str_22
		mov StringUtils.rbx, 20
		call StringUtils.PROC_PrintBanner
		pop r8
		pop rdi
		pop rsi
		pop rdx
		pop rcx
		pop rbx
		done
	}
}