Programming - Assembly Arrays and Memory Instructions

    Hello again my friends! Today we will get into Arrays and Memory Instructions, that will let us do stuff on variables and arrays. I will first start out with how we declare variables ( reminder ) and arrays ( new ) in the .data part of our code and then we will take a look at how we do stuff on our variables and arrays using the lw and sw memory instructions. So, let's get started!


Variable/Array Declaration:

    As I already told you in our first Assembly post, our code is split into 2 parts: one that contains variable/array/string declarations and one that contains our code/instructions. I already showed you how to declare some kind of variables also. Those were integers, characters and strings, but this time let's put all of them in one place, to make it easier to call back if needed.

Declaring Variables:

    To declare variables we use the following format:

 name: storage_type value(s) 

The name can be anything we like.

The storage_type's I will use are the following:

  • .word for integers
  • .byte for characters
  • .asciiz for strings (to be outputed)
  • .space for memory allocation of specific byte size

    When declaring integers, characters and strings we put the value, but when declaring a space and therefore and array we put the number of bytes we want to allocate.

Array declaration:

    So, to declare an array we use a similar syndax to the variables, but this time we simple allocate enough memory for our array directly ( the same way we defines static arrays in C ) knowing how much each element takes. An integer in MIPS Assembly need 4 Bytes or 1 Word and an character needs 1 Byte for example. 

  • To create an character array ( string ) we simply have to allocate N Bytes for N characters.
  • To create an integer array we simply have to allocate 4*N Bytes for N integers.

So, our declaration in code looks like this:

array_name: .space N # N is size in Bytes to allocate

To create an integer array for 5 integers we will have to use the following code:

A: .space 20

We will get into dynamic arrays some posts later on, when we are finished with the basic and easy stuff!


Memory Instructions:

    When declaring a variable or an array we have it stored inside of our memory. But, the instructions used mostly use registers as "parameters". That's why we need to use instructions to load from a memory address and to save into a memory address. The name of our variable is actually an shortcut to its location inside of our memory. Let's start out with loading and then get into storing ( saving ).

Loading from memory:

    To load an value from a memory address and store it inside of a register we use one of two instructions ( mostly ). One is for characters/bytes and the other one for integers/words. 

The instuctions are written similar and look like this:

lb $rt, Address ($rs) # load byte from Address + $rs value
lw $rt, Address ($rs) # load word from Address + $rs value

    The index of the first element of an array is stored inside of the address of the "name" of the array. That's why to access the first element of integer array A and store it inside of register $t0 we have to use the following:

lw $t0, A($0)

But, when wanting to do stuff like that in a loop we would have to use another register and that's exactly what we will do.

So, for accesing the 3rd item we need to add 8 (4 * 2) Bytes into the Address of our Array ( an Array is stored sequentially ).

Our Code would look like this:

li $t1, 8
lw $t0, A($t1)

We could edit this $t1 register value in each loop to iterate through each element of the array and do stuff like sorting, printing and so on...


Storing into memory:

    To store a value of a register inside of a memory address, we use two similar instructions. 

Those are:

sb $rt, Address ($rs) # store byte into Address + $rs value
sw $rt, Address ($rs) # store word into Address + $rs value

So, to store the integer value of register $t0 into the 5th index of integer array A we would use the following code:

li $t1, 16
sw $t0, A($t1) # store into address A + 16

We could again do this inside of the loop incrementing the value of register $t1 every iteration to do stuff like sorting or even storing reverse!


Coding Section:

    Last but not least, we got into the coding section. I have two Codes for you that do stuff into Arrays. The first one finds the sum of an integer array and the second one prints the max value of an integer array. We will get the values for our arrays in both of them as input and we will only get positive values! We will also use strings for outputing messages. So, let's get started!

Code 1:

    We declare an Integer array of 6 integers, get the values as input and store them in the array, calculate the sum of the integers and print it and then terminate our programm.

.data
Vector: .space 24 # Declare Integer Array
                  # for 24 / 4 = 6 Integers
# declare strings
get: .asciiz "Give an integer: "
sum: .asciiz "The sum is: "

.text
main:

li $t1,0 # loop counter gets value 0

for1:
# print message for getting integer
li $v0,4
la $a0,get
syscall

# get integer a input
li $v0, 5
syscall
move $t0,$v0

# store in array
sw $t0,Vector($t1) 

# increment loop counter   
addi $t1,$t1,4      

# check counter and loop or continue
blt $t1,24,for1 # counter<24 -> jump to "for1"


li $t1,0 # loop counter gets value 0 again
li $s0,0 # sum value gets value 0

for2:
# load from array
lw $t0,Vector($t1)

# calculate sum adding new read value
add $s0,$s0,$t0

# increment loop counter
addi $t1,$t1,4

# check counter and loop or continue
blt $t1,24,for2 # counter<24 -> jump to "for2"

# print message for outputing sum
li $v0,4
la $a0,sum
syscall

# print sum
li $v0,1
move $a0,$s0
syscall

# terminate programm
li $v0,10
syscall   


Code 2:

  We declare an Integer array of 5 integers, get the values as input and store them in the array, find the max of the array and print it and terminate our programm.

.data
Vector: .space 20 # Declare Integer Array
                  # for 20 / 4 = 5 Integers
# declare Strings
get: .asciiz "Give an integer: "
max: .asciiz "The max is: "

.text
main:

li $t1,0 # counter gets value of 0

for1:
# print message for getting integer
li $v0,4
la $a0,get
syscall

# get integer input
li $v0, 5
syscall
move $t0,$v0

# store in array
sw $t0,Vector($t1)

# increment loop counter
addi $t1,$t1,4

# check counter and loop or continue
blt $t1,20,for1 # counter<20 -> jump to "for1"

lw $s0,Vector($0) # max gets value of first number
li $t1,4 # counter gets value of 4

for2:
# load from array
lw $t0,Vector($t1) 

# check if not max
blt $t0,$s0,not_max

# set as new max 
move $s0,$t0
# no jump cause we want the code to be run

not_max:
# increment loop counter
addi $t1,$t1,4

# check counter and loop or continue
blt $t1,20,for2 # counter<20 -> jump to "for2"

# print message for outputing max
li $v0,4
la $a0,max
syscall

# print max
li $v0,1
move $a0,$s0
syscall

# terminate programm
li $v0,10
syscall  


This is the end of today's post. Hope you enjoyed it and learned something new! Next post will be somekind of example for going from C Code into Assembly Code, using everything we learned so far!

Bye!

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now