.globl __start

.include "..\\SrcAll\BasicMacros.asm"

.text
__start:

	j LogicalOps        # Переход к метке LogicalOps // Jump to the label LogicalOps
	j BitShifts         # Переход к метке BitShifts // Jump to the label BitShifts
	j SetCommands       # Переход к метке SetCommands // Jump to the label SetCommands
	
# Логические операции // Logical operations
LogicalOps:	
	li a0,0x12345678    # a0=12345678
	li a1,0x12345678    # a1=12345678
	li a2,0xFFFF0000    # a2=FFFF0000
	
	jal MonitorA0A1A2 	#; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	
	xor  a0,a0,a2		#;A0= A0 Xor X2 - исключающее ИЛИ
	xori a1,a1,0xFF		#;A0= A0 Xor 0xFF (immediate has 1 byte limit) // A0= A0 Xor 0xFF - исключающее ИЛИ (размер непосредственного числа в качестве операнда ограничен одним байтом)
	
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	and  a0,a0,a2		#;A0= A0 And X2 - логическое И
	andi a1,a1,0xFF		#;A0= A0 And 0xFF (immediate has 1 byte limit) // A0= A0 And 0xFF - логическое И (размер непосредственного числа в качестве операнда ограничен одним байтом)
	
	li a2,0xCD000000    # a2=CD000000
	or a1,a1,a2         # A1= A1 Or A2 - логическое ИЛИ
	ori a0,a0,0xCD      # A0= A0 Or 0xCD (immediate has 1 byte limit) // A0= A0 Or 0xCD - логическое ИЛИ (размер непосредственного числа в качестве операнда ограничен одним байтом)
	
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	#; LI is a psuedo instruction - the assembler uses LUI and Add commands to make up the actual command // LI - это псевдоинструкция, которая использует команды LUI и Add, чтобы получить нужный результат
	
	lui a0,0xFF			 #;A0=0x000FF000
	lui a1,0xFFFF		 #;A1=0x0FFFF000
	lui a2,0xFFFFF		 #;A2=0xFFFFF000
	#;lui a1,0xFFFFFF #; This wont work - 5 character limit
	jal MonitorA0A1A2    #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	li a2,0x00001234	# A2=0x00001234
	not a0,a2			#;Flip bits in a2. Result in a0 // Перевернуть биты (поменять на противоположные) в регистре a2. Результат в a0
	neg a1,a2			#;Flip bits in a2, Add 1 // Перевернуть биты (поменять на противоположные) в регистре a2 и добавить 1. Результат в a1
	
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	jal NewLine # Переход к метке NewLine с сохранением адреса возврата в регистре RA // Jump to the label NewLine with saving return address to RA register
	j Shutdown # Переход к метке Shutdown // Jump to the label shutdown
	
#;Bit Shifts / Битовые сдвиги
BitShifts:
	
	li a4,4			# a4=4
	li a0,0x80002001	# a0=80002001
	mv a1,a0		# a1=a0
	mv a2,a0		# a2=a0
	li a3,1			# a3=1
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
ShiftLoop:
	#;sll a1,a1,a3		#;Shift Bits from a1 Left by a3, result is in a1 // Сдвинуть число из a1 влево на a3 разрядов, результат в a1
	slli a1,a1,1		#;Shift Bits from a1 Left by 1, result is in a1 // Сдвинуть число из a1 влево на 1 разряд, результат в a1
	srl  a2,a2,a3		#;Shift bits from a2 Right by a3, result is in a2 // Сдвинуть число из a2 вправо на a3 разрядов, результат в a2
	#;srli a2,a2,1		#;Shift bits from a2 Right by 1, result is in a2 // Сдвинуть число из a2 вправо на 1 разряд, результат в a2
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	addi a4,a4,-1		# a4=a4-1
	bne a4,zero,ShiftLoop	# If a4 not equivalent to zero, jump to the label ShiftLoop // Если значение в a4 не равно нулю - переход на метку ShiftLoop
	
	
	jal NewLine # Переход к метке NewLine с сохранением адреса возврата в регистре RA // Jump to the label NewLine with saving return address to RA register
	
	li a4,4			# a4=4
	li a0,0x80002001	# a0=80002001
	mv a1,a0		# a1=a0
	mv a2,a0		# a2=a0
	li a3,1			# a3=1
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
# Арифметкический (с учётом знака) сдвиг // Arithmetic (with sign accounting) shift
ArithmeticShiftLoop:
	srai a1,a1,1		#;Arithmetic Shift bits from a1 Right by 1, result is in a1 // Арифметический сдвиг числа из a1 на 1 разряд вправо, результат в a1
	sra  a2,a2,a3		#;Arithmetic Shift bits from a2 Right by a3, result is in a2 // Арифметический сдвиг числа из a2 на a3 разрядов вправо, результат в a2
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	addi a4,a4,-1		# a4=a4-1
	bne a4,zero,ArithmeticShiftLoop	# If a4 not equivalent to zero, jump to the label ArithmeticShiftLoop // Если значение в a4 не равно нулю - переход на метку ArithmeticShiftLoop
	
	jal NewLine # Переход к метке NewLine с сохранением адреса возврата в регистре RA // Jump to the label NewLine with saving return address to RA register
	j Shutdown		# Переход на метку Shutdown // Jump to the label Shutdown
	
#;Set if LessThan / Greater To	// Установить значение регистра при выполнении условия
SetCommands:
	li a0,0			# a0=0
	li a1,20		# a1=20
	li a2,15		# a2=15
	
	sltu a0,a1,a2		#;Set A0=1 if A1<A2 else 0 (unsigned) // Установить A0=1, если A1<A2, иначе - установить A0=0 (для чисел без знака)
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	sgtu a0,a1,a2		#;Set A0=1 if A1>A2 else 0 (unsigned) // Установить A0=1, если A1>A2, иначе - установить A0=0 (для чисел без знака)
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
	li a0,0			# a0=0
	li a1,20		# a1=20
	li a2,-100		# a2=-100
	
	jal NewLine # Переход к метке NewLine с сохранением адреса возврата в регистре RA // Jump to the label NewLine with saving return address to RA register
	
	slt a0,a1,a2		#;Set A0=1 if A1<A2 else 0 (signed) // Установить A0=1, если A1<A2, иначе - установить A0=0 (для чисел со знаком)
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	sgt a0,a1,a2		#;Set A0=1 if A1>A2 else 0 (signed) // Установить A0=1, если A1>A2, иначе - установить A0=0 (для чисел со знаком)
	jal MonitorA0A1A2   #; Show A0,A1,A2 to screen // Отобразить A0,A1,A2 на экране // Переход к метке MonitorA0A1A2 с сохранением адреса возврата в регистре RA // Jump to the label MonitorA0A1A2 with saving return address to RA register
	
Shutdown:
  #; ends the program with status code 0 // завершение программы с кодом состояния 0
  li a7, 10			# a7=10
  ecall				# системный вызов
  
# Showing the contents of registers A0,A1,RA,PC // Отображение содержимого регистров A0,A1,RA,PC
MonitorA0A1RAPC:
	pushAs				# Save registers A0..A7 into stack // Сохранить регистры A0..A7 в стеке
	push ra				# Save RA register into stack // Сохранить значение регистра RA в стеке
		push a6			# Save A6 register into stack // Сохранить значение регистра A6 в стеке
			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	# a7=a0
			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'
			li a6,'1'
			mv a7,a1
			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,'r'
			li a6,'a'
		pop 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'
		li a6,'c'
	pop a7
	push 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-строку.  
	pop ra
	popAs
	ret
 
MonitorA0A1A2:
	push ra
	pushAs
	    li a5,'a'
		li a6,'0'
		mv a7,a0
		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'
		li a6,'1'
		mv a7,a1
		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'
		li a6,'2'
		mv a7,a2
		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         
	popAs
	pop ra
	ret
  
.include "..\\SrcAll\monitor.asm"  
.include "..\\SrcAll\BasicFunctions.asm"  
  
#;All Data must go in the Data Segment - cannot read from code segment
.data
TestData:
	.byte 0xF0,0xF1,0xF2,0xF3	#;Little Endian - so this is $F3F2F1F0
	.byte 0,0,0,0,0,0,0,0,0,0,0,0
JumpAndLinkTo: 
  .string "JAL "
  .byte 255 
JumpTo: 
  .string "J   "
  .byte 255 
JumpToRegister: 
  .string "JR  "
  .byte 255 
JumpAndLinkToRegister: 
  .string "JALR"
  .byte 255 
