
.globl __start

.eqv  test,3
# Используем файл ..\\SrcAll\BasicMacros.asm / Use file ..\\SrcAll\BasicMacros.asm
.include "..\\SrcAll\BasicMacros.asm"

# Вывести содержимое регистров A0, A1, RA, PC / Print the contents of registers A0, A1, RA, PC
.macro MonitorA0A1RAPCm
	push ra # Сохранить значение RA в стеке / Save RA value into stack
		mv a6,ra # Move RA->A6 / Загрузить значение из RA в A6
		jal MonitorA0A1RAPC # Переход к метке MonitorA0A1RAPC с сохранением адреса возврата в RA / Jump to label MonitorA0A1RAPC with saving return address into RA
	pop ra # Вернуть значение RA из стека / Return RA value from stack
.end_macro
# Вывести содержимое стека на экран / Print the contents of stack on the screen
.macro DumpStack
	jal MonitorA0A1PCSP # Переход к метке MonitorA0A1PCSP (Вывод A0, A1, PC, SP на экран) с сохранением адреса возврата в RA / Jamp to label MonitorA0A1PCSP (Print A0, A1, PC, SP on the screen) with saving return address into RA

	li a6,2			# a6=2 ;Line Count / Количество строк
	jal MemDumpNoLabel	#;Dump Stack to screen / Вывод стека на экран / Переход к метке MemDumpNoLabel с сохранением адреса возврата в RA / Jump to label MemDumpNoLabel with saving return address into RA
	jal NewLine		# Переход к метке NewLine с сохранением адреса возврата в RA / Jump to label NewLine with saving return address into RA
	
.end_macro
.text
__start:
	li ra,0			# ra=0

	#;j StackTest		# Переход к метке StackTest / Jump to label StackTest
	
	#;j TestEqualsNotequals #;= != # Переход к метке TestEqualsNotequals / Jump to label TestEqualsNotequals
	#;j TestLessGreaterUnsigned #;< <= > >= # Переход к метке TestLessGreaterUnsigned / Jump to label TestLessGreaterUnsigned
	#;j TestLessGreaterSigned #;< <= > >= # Переход к метке TestLessGreaterSigned / Jump to label TestLessGreaterSigned
	j TestLessGreaterZero	#;<0 <=0 >0 >=0 # Переход к метке TestLessGreaterZero / Jump to label TestLessGreaterZero
	
	
	
StackTest:
	mv a7,sp		# Загрузить значение из SP (адрес вершины стека) в A7 / Move value from SP (stack pointer) into A7
	addi a7,a7,-16		# a7=a7-16
	
	li a0,0xF4F3F2F1	# a0=F4F3F2F1
	DumpStack		#;Вывод стека на экран / Dump Stack to screen
	
	addi sp,sp,-4		#;push a0
	sw a0,0(sp)    		#;push a0
		li a0,0		# a0=0
		DumpStack	#;Вывод стека на экран / Dump Stack to screen
		jal SubTest	# Переход к метке SubTest с сохранением адреса возврата в RA / Jump to label SubTest with saving return address into RA
	lw a0,0(sp)		#;pop a0
	addi sp,sp,4		#;pop a0
	
	DumpStack		#;Вывод стека на экран / Dump Stack to screen
	jal MonitorA0A1PCSP	# Переход к метке MonitorA0A1PCSP с сохранением адреса возврата в RA / Jump to label MonitorA0A1PCSP with saving return address into RA
	j Shutdown		# Переход к метке Shutdown / Jump to label Shutdown

SubTest:
	addi sp,sp,-4		#;push ra
	sw ra,0(sp)   		#;push ra
		li a0,0x11223344 # a0=11223344
		push a0		# Положить содержимое a0 в стек / Push contents of a0 into stack
			DumpStack	#;Dump Stack to screen / Вывести содержимое стека на экран
		pop a0		# Вернуть значение a0 из стека / Turn back a0 contents from stack
		DumpStack		#;Dump Stack to screen / Вывести содержимое стека на экран
		
	lw ra,0(sp)			#;pop ra
	addi sp,sp,4		#;pop ra
	ret #;jr RA / команда соответствует jr RA
	
	
	
	
#; These have psuedo-ops: BEQZ, BNEZ, BLEZ, BGEZ, BLTZ, BGTZ / BEQZ, BNEZ, BLEZ, BGEZ, BLTZ, BGTZ - псевдооперации
# Проверка больше ли нуля число / Check if number is greater than zero
TestLessGreaterZero:
	#;li a0,-100		#;TestVal1 / a0=-100
	li a0,0				#;TestVal1 / a0=0

	jal MonitorA0A1 # Переход к метке MonitorA0A1 с сохранением адреса возврата в RA / Jump to label MonitorA0A1 with saving return address into RA
	
	beq a0,zero,PrintEquals		#;Compare a0 to zero (x0 register) / Jump to the label if a0=0 / Сравнение с нулём (x0 или zero всегда равен нулю) / Переход, если a0=0
	bne a0,zero,PrintNotEquals	#;Compare a0 to zero (x0 register) / Jump to the label if a0 not equal to 0 / Сравнение с нулём (x0 или zero всегда равен нулю) / Переход, если a0 не равен 0
	
	#;blt a0,zero,PrintLessThan			#;is a0 < zero (x0 register) / Jump if a0<0 / Сравнение с нулём (x0 или zero всегда равен нулю) / Переход, если a0<0
	#;bgt a0,zero,PrintGreaterThan		#;is a0 > zero (x0 register) / Jump if a0>0 / Сравнение с нулём (x0 или zero всегда равен нулю) / Переход, если a0>0

	#;ble a0,zero,PrintLessThanEquals		#;is a0 <= zero (x0 register) / Jump if a0<=0 / Сравнение с нулём (x0 или zero всегда равен нулю) / Переход, если a0<=0
	#;bge a0,zero,PrintGreaterThanEquals	#;is a0 >= zero (x0 register) / Jump if a0>=0 / Сравнение с нулём (x0 или zero всегда равен нулю / Переход, если a0>=0
	
	j Shutdown				# Переход к метке Shutdown / Jump to the label Shutdown

# Проверка, больше ли числа со знаком /	Check if number is greater than signed number
TestLessGreaterSigned:
	li a0,-100			#;TestVal1 / a0=-100

	li a1,99			#;Less Than Test / Проверка, меньше ли число / a1=99
	 #;li a1,-100		#;Equals Test / Проверка, равно ли число другому / a1=-100
	#;li a1,-101		#;Greater than Test / Проверка, больше ли число / a1=-101
	
	jal MonitorA0A1		# Переход к метке MonitorA0A1 с сохранением адреса возврата в RA / Jump to label MonitorA0A1 with saving return address into RA
	
	#;blt a0,a1,PrintLessThan			#;is a0 < a1 / Jump if a0<a1 / Переход, если a0<a1
	#;bgt a0,a1,PrintGreaterThan		#;is a0 > a1 / Jump if a0>a1 / Переход, если a0>a1

	ble a0,a1,PrintLessThanEquals		#;is a0 <= a1 / Jump if a0<=a1 / Переход, если a0<=a1
	bge a0,a1,PrintGreaterThanEquals	#;is a0 >= a1 / Jump if a0>=a1 / Переход, если a0>=a1
	
	j Shutdown				# Переход к метке Shutdown / Jump to the label Shutdown

	
# Проверка больше ли числа без знака / Check if number is greater than unsigned number
TestLessGreaterUnsigned:
	li a0,100			#;TestVal1 / a0=100

	li a1,99			#;Less Than Test / Проверка, меньше ли число / a1=99
	#; li a1,100		#;Equals Test / Проверка, равно ли число / a1=100
	li a1,101			#;Greater than Test / Проверка, больше ли число / a1=101
	
	jal MonitorA0A1		# Переход к метке MonitorA0A1 с сохранением адреса возврата в RA / Jump to label MonitorA0A1 with saving return address into RA
	
	#;bltu a0,a1,PrintLessThan			#;is a0 < a1 / Jump if a0<a1 (signed) / Переход, если a0<a1 (со знаком)
	#;bgtu a0,a1,PrintGreaterThan		#;is a0 > a1 / Jump if a0>a1 (signed) / Переход, если a0>a1 (со знаком)
	
	bleu a0,a1,PrintLessThanEquals		#;is a0 <= a1 / Jump if a0<=a1 (signed) / Переход, если a0<=a1 (со знаком)
	bgeu a0,a1,PrintGreaterThanEquals	#;is a0 >= a1 / Jump if a0>=a1 (signed) / Переход, если a0>=a1 (со знаком)
	
	j Shutdown				# Переход к метке Shutdown / Jump to the label Shutdown

# Проверка, равно ли число другому числу / Check if number equal to other number	
TestEqualsNotequals:
	li a0,100			#;TestVal1 / a0=100

	#; li a1,100		#;Equals Test / Проверка на равенство / a1=100
	li a1,101			#;Not Equals Test / Проверка на неравество / a1=101
	
	jal MonitorA0A1		# Переход к метке MonitorA0A1 с сохранением адреса возврата в RA / Jump to label MonitorA0A1 with saving return address into RA
	
	beq a0,a1,PrintEquals		#;Compare a0 to a1 / Jump if a0=a1 / Переход, если a0=a1
	bne a0,a1,PrintNotEquals	#;Compare a0 to a1 / Jump if a0 not equal to a1 / Переход, если a0 не равно a1
	
	j Shutdown			# Переход к метке Shutdown / Jump to the label Shutdown

# Завешение программы / Termination of the program	
Shutdown:
  #; ends the program with status code 0 / Завершение программы с кодом состояния 0
  li a7, 10				# a7=10
  ecall					# Системный вызов / System call
 
# Вывод на экран в случае, если числа  не равны / Printing to screen if numbers are not equal
PrintNotEquals:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'!'		# Load ASCII code of '!' symbol into a1 / Загрузить ASCII-код символа '!' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
		li a1,'='		# Load ASCII code of '=' symbol into a1 / Загрузить ASCII-код символа '=' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label
# Вывод на экран в случае, если числа равны / Printing to screen if numbers are equal
PrintEquals:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'='		# Load ASCII code of '=' symbol into a1 / Загрузить ASCII-код символа '=' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label
# Вывод на экран в случае, если первое число меньше / Printing to screen if first number is less
PrintLessThan:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'<'		# Load ASCII code of '<' symbol into a1 / Загрузить ASCII-код символа '<' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label
# Вывод на экран в случае, если первое число меньше или равно / Printing to screen if first number is less or equal
PrintLessThanEquals:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'<'		# Load ASCII code of '<' symbol into a1 / Загрузить ASCII-код символа '<' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
		li a1,'='		# Load ASCII code of '=' symbol into a1 / Загрузить ASCII-код символа '=' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label
# Вывод на экран в случае, если первое число больше / Printing to screen if first number is greater
PrintGreaterThan:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'>'		# Load ASCII code of '>' symbol into a1 / Загрузить ASCII-код символа '>' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label
# Вывод на экран в случае, если первое число больше или равно / Printing to screen if first number is greater or equal
PrintGreaterThanEquals:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
		li a1,'>'		# Load ASCII code of '>' symbol into a1 / Загрузить ASCII-код символа '>' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
		li a1,'='		# Load ASCII code of '=' symbol into a1 / Загрузить ASCII-код символа '=' в A1
		jal PrintChar		# Переход к метке PrintChar с сохранением адреса возврата в RA / Jump to label PrintChar with saving return address into RA 
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	j Shutdown			# Переход к метке Shutdown / Jump to the Shutdown label

# Вывод "a0" и содержимого a0, вывод "a1" и содержимого a1 / Printing "a0" and contents of a0, printing "a1" and contents of a1
MonitorA0A1:
	push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
	pushAs				# Сохранение значений регистров a0..a7 в стеке / Push the contents of registers a0..a7 into stack
	    	li a5,'a'		# Load ASCII code of 'a' symbol into a5 / Загрузить ASCII-код символа 'a' в A5
		li a6,'0'		# Load ASCII code of '0' symbol into a6 / Загрузить ASCII-код символа '0' в A6
		mv a7,a0		# a0->a7 / Загружаем содержимое a0 в a7
		jal ShowRegTextB        #   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.    
		li a5,'a'		# Load ASCII code of 'a' symbol into a5 / Загрузить ASCII-код символа 'a' в A5
		li a6,'1'		# Load ASCII code of '1' symbol into a6 / Загрузить ASCII-код символа '1' в A6
		mv a7,a1		# a1->a7 / Загружаем содержимое a1 в a7
		jal ShowRegTextB        #   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.        
		jal NewLine         	#; Jump to the code that outputing the symbol that moving to the next line / Переход к коду, выводящему символ перехода на следующую строку 
	popAs				# Return A0..A7 from stack / Вернуть содержмое регистров A0..A7 из стека
	pop ra				# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	ret				#;jr RA / команда соответствует jr RA (переход по адресу, находящемуся в RA)
# Вывод "a0" и содержимого a0, "a1" и содержимого a1, "pc" и содержимого pc, "sp" и содержимого sp / Printing "a0" and contents of a0, "a1" and contents of a1, "pc" and contents of pc, "sp" and contents of sp
MonitorA0A1PCSP:
	mv a4,sp					# sp->a4 / Загружаем содержимое sp в a4
	addi a4,a4,4					# a4=a4+4
	push ra						# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
	pushAs						# Сохранение значений регистров a0..a7 в стеке / Push the contents of registers a0..a7 into stack
		push a4					# Сохранение значения регистра a4 в стеке / Push the contents of a4 register into stack
			push ra				# Сохранение значения регистра ra в стеке / Push the contents of ra register into stack
				li a5,'a'		# Load ASCII code of 'a' symbol into a5 / Загрузить ASCII-код символа 'a' в A5
				li a6,'0'		# Load ASCII code of '0' symbol into a6 / Загрузить ASCII-код символа '0' в A6
				mv a7,a0		# a0->a7 / Загружаем содержимое a0 в a7
				jal ShowRegTextB        #   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.        
				li a5,'a'		# Load ASCII code of 'a' symbol into a5 / Загрузить ASCII-код символа 'a' в A5
				li a6,'1'		# Load ASCII code of '1' symbol into a6 / Загрузить ASCII-код символа '1' в A6
				mv a7,a1		# a1->a7 / Загружаем содержимое a1 в a7
			jal ShowRegTextB                #   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.       
			li a5,'p'			# Load ASCII code of 'p' symbol into a5 / Загрузить ASCII-код символа 'p' в A5
			li a6,'c'			# Load ASCII code of 'c' symbol into a6 / Загрузить ASCII-код символа 'c' в A6
			pop a7				# Возвращение значения в регистр a7 из стека. / Turn back the contents into a7 register from stack
			# Здесь в a7 помещается то, что лежало в ra, а в ra лежит содержимое счётчика команд pc / Here we put into a7 ex-contents of ra and ra contains program counter pc
			jal ShowRegTextB              	#   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.       
			li a5,'s'			# Load ASCII code of 's' symbol into a5 / Загрузить ASCII-код символа 's' в A5
			li a6,'p'			# Load ASCII code of 'p' symbol into a6 / Загрузить ASCII-код символа 'p' в A6
		pop a7					# "Выталкивание" значения в регистр a7 из верхушки стека. В тот момент стеке было значение регистра a4 (ранее, sp). Теперь оно в a7.  / Pull out value from top of the stack into a7. In this moment in stack was value of a4 (sp before). Now it's in a7.
		jal ShowRegTextB             #   ;A5 A6 : A7 - contents of registers will be printed on the screen: ASCII-codes of A5, A6 contents. Value in A7 will be converted into ASCII-String / A5 A6 : A7 Содержимое регистров отобразится на экране. В A5, A6 - ASCII-коды отображаемых символов. Содержимое A7 сбудет преобразовано из числа в ASCII-строку.      
		
	popAs						# Return A0..A7 from stack / Вернуть содержмое регистров A0..A7 из стека
	pop ra						# Возвращение значения в регистр ra из стека / Turn back the contents into ra register from stack
	ret						#;jr RA / команда соответствует jr RA (переход по адресу, находящемуся в RA)
  
.include "..\\SrcAll\monitor.asm"  
.include "..\\SrcAll\BasicFunctions.asm"  
  
#;All Data must go in the Data Segment - cannot read from code segment / Все данные должны лежать в сегменте данных. Из сегмента кода читать нельзя.
.data
