Global variables

Declare a global variable named count initialized to 0. Make two functions:

Then in main, call count_up and count_down a few times. Finally, print out the value of count.

Solution:

.data
	count: .word 0

.text

# --------------------------------------
count_up:
	lw	t0, count
	add	t0, t0, 1
	sw	t0, count
	jr	ra

# --------------------------------------
count_down:
	lw	t0, count
	sub	t0, t0, 1
	sw	t0, count
	jr	ra

# --------------------------------------
.globl main
main:
	jal	count_up   # 1
	jal	count_up   # 2
	jal	count_up   # 3
	jal	count_down # 2

	lw	a0, count
	li	v0, 1
	syscall

Endianness

If you are unsure what endianness your computer is, you can write a program to test it:

  1. Make a word-sized variable initialized to a 8-digit hexadecimal value that’s different on the two ends.
    • e.g. 0xBEEFC0DE or 0xDEADBEEF or 0xCAFEFACE or even 0x11223344 if you’re boring
  2. Use the lbu instruction to load the first byte of that variable.
    • it’s fine!
  3. Use syscall 34 to print the value that you loaded.
    • this prints an int in hexadecimal instead of decimal.

Look at the output. Which end of the original value is it? That’s what endianness it is. e.g. if you used 0xBEEFC0DE:

Solution:

.data
	var: .word 0xBEEFC0DE
.text
.globl main
main:
	lbu	a0, var # loads the first byte of var, whichever end that happens to be
	li	v0, 34
	syscall

Why does this work?

var is at address 0x10010000 (check the labels window when you assemble). 0xBEEFC0DE is 4 bytes long in memory. If the CPU is big-endian, then the byte at 0x10010000 will be the “big end” of the number - so it will be 0xBE. But unless you’re running MARS on a really strange computer, it’s probably little-endian, so the bytes will be in this order:

So, when we do lbu a0, var, it will load the byte at 0x10010000 - which is 0xDE.