Labels

Labels are a convenient way to reference a specific location in memory. It is basically the only abstraction that we get to make our lives a little easier when programming assembly, because otherwise we would need to manually count memory addresses, which is incredibly tedious. When MARS assembles the program (translates it into binary), labels are replaced by their actual address values.

For reasons that will make sense later, whenever using immediate values in an instruction, the immediate value MUST fit into 16 bits. But that is a problem because memory addresses are 32 bits.

Because of this, we cannot directly load an address from a label into a register (via something like addi $t0, $zero, MY_LABEL). So instead we use the la pseudo instruction, which uses two separate instructions to load the upper 16 bits of the address into the register, and then load the lower 16 bits into the register

This is why we NEED to use la before doing anything else with the label. It is to get that entire memory address into a register.

Loading/Saving

Once we have the address, we can use the load and store instructions to read/write the value located at the address to. This is like dereferencing a pointer in C.

Create a label, read from and write to it

.data
MY_NUM: .word 1234

.text
		# get the address to the number.
		la   $t0, MY_NUM     # int* t0 = MY_NUM
		
		# get the actual value
		lw   $t1, 0($t0)     # int  t1 = *t0
		
		# increment the value, overwrite the old value in memory with the new one.
		addi $t1, $t1, 1     # t1 += 1
		sw   $t1, 0($t0)     # *t0 = t1

Create and use strings, working with chars

.data
MY_STRING: .asciiz "Hello, World!\\n"

.text
		la   $t0, MY_STRING   # char* t0 = MY_STRING

		# Note how we use lb (load byte), and we only get the first character of the string. A string is just an array of characters. 
		# We can't store an entire string into a register. Its too large. So we just store a pointer to the start of the string.
		# Then we can load individual characters using lb.

		lb   $t1, 0($t0)      # t1 = *t0 = 'H'
		lb   $t2, 6($t0)      # t2 = *(t0+6) = ' '
		
		
		# fun fact: characters are just numbers too! There is a unique ascii code for each character
		# You can find an ascii table on the website, in the "materials" category.
		
		add  $t3, $t1, $t2   # t3 = 'H' + ' '
												 # this is the same as doing 0x20 + 0x46
												 # the result is 0x68, or the ascii character 'h'

		# another fun fact when using i instructions, you can enter a character for your immediate value.
		addi $t4, $zero, 'o'
		sb   $t4, 5($t0)     # *(t0+5) = 'o'
		# the string in memory now says "Helloo World!\\n"