Programming - Assembly Basic Coding Structure

    After talking about C and Java so much, I wanted to start with another Language. The Programing Language I chose is Assembly! I already said in previous posts, that writing in Assembly takes a lot of time and patience. But knowing how the Code is being run on the CPU, after being translated into Assembly Code, helps us make our Code faster and to find some Bugs in more advanced Programms, that else would be missed! So, without further do, let's get started!


Assembly "Version":

    I will talk about MIPS Assembly, cause that's the type of Assembly we learned in our University and I have a lot of experience and many many Codes, Notes and other stuff that will help me explain it to you. The Syntax in other Assembly Languages doesn't change a lot tho! There will be differences in the naming and the parameters of our functions, but the basic "logic" stays the same. So, knowing how to write Assembly for MIPS CPU's will not put you back and you can jump easily into Intel and AMD CPU Assembly Coding :)

To run our Code we will use a software called QtSpim that you can find here

    This Software let's us run our Code Step after Step or normally, see the Content of all the Registers, the .data and the .text regions of our Assembly Code (more information for all that comes in a bit).


Structure:

    All the Instructions we will use are 32 bits (4 bytes) long. This Instructions are executed in one CPU and we will use Registers for getting information like values, addresses etc. for all the different kinds of Instructions there are. The Higher Level Code that we write (C, Java etc.) gets translated into Assembly Code when Compiling it! So, our CPU reads Instructions like the ones that we will talk about in all our Assembly Posts!

Registers:

They are small 32-bit (4 byte) memory units, from which an 32-bit MIPS CPU has 32

Those Registers can be accesses using the:

  • Register Number with an $ in front like this: $5, $15, ...
  • Equivalent Names that some have like this : $t0, $s1, ...

The Registers are:

  • $0 or $zero that has a value of 0 always
  • $1 that is reserved by the assembler
  • $2, $3 or $v0, $v1 that will return function results
  • $4-7 or $a0-3 that are used as function parameters
  • $8-15 or $t0-7 that are caller saved temporaries (more in functions)
  • $16-23 or $s0-7 that are callee saved values (more in functions)
  • $24-25 or $t8-9 that are temporaries if more are needed
  • $26-27 or $k0-1 that are reserved for the interrupt handler
  • $28 or $gp that is the global program pointer
  • $29 or $sp that points to the last position of the stack pointer
  • $30 or $s8 or $fp that is a saved value or a frame pointer
  • $31 or $ra that contains the return address (more in functions)

Datatypes:

The Datatypes are the following:

  • integer (4 bytes) or .word when coding
  • character (1 byte) or .byte when coding 
  • string ("unlimited bytes", one for each character) or .asciiz when coding

When inputing we will put:

  • numbers as is
  • characters enclosed in single quotes (' ')
  • strings enclosed in double quotes (" ")

Code Structure:

    The Code is split in 2 parts: one contains the variables and one the code itself. Those 2 are called .data and .text. 

In .data we declare variables (integers, strings, arrays) using the following format:

name: storage_type value(s)

 So, we could create an integer called num with value 3 like that:

num: .word 3

In there we will later on declare strings that we want to print out in the terminal/console.


In .text we will call instructions to do stuff with our Registers and Variables and contain functions.

 A Instruction that increments the value of register $t0 by 1 looks like this for example:

addi $t0, $t0, 1 # t0 = t0 + 1

    As you can see until now, we don't put semicolons (;) like in C or Java, cause every line is an Instruction! We also have to use the right small/capital letter names and so on, cause the language is also cap-senstitive. Also, comments are done using the # symbol instead of the // or /* */ we used to use in C or Java. And last but not least the first Code that will be run, will be located inside of the main function and we can have more than 1 functions.

So, our Code Structure will look like this:

.data
#variables
.text
main:
#instructions


Example Code:

    Last for today here a Example Code. Try running the following Code to set everything up in QtSpim. The file needs to have a name that ends with .s like this: test.s

test.s:

.data
# Constant strings to be output to the terminal
promptInt: .asciiz "Please input an integer: "
resultInt: .asciiz "Next integer is: "
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."

.text
main:
# prompt for an integer
li $v0,4 # code for print_string
la $a0,promptInt # point $a0 to prompt string
syscall # print the prompt

# get an integer from the user
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
move $t0,$v0 # move the resulting int to $t0

# compute the next integer
addi $t0, $t0, 1 # t0 <-- t0 + 1

# print out text for the result
li $v0,4 #code for print_string
la $a0,resultInt # point $a0 to result string
syscall # print the result string

# print out the result
li $v0,1 # code for print_int
move $a0,$t0 # put result in $a0
syscall # print out the result

# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed

# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey

# wait for input by getting an integer from the user
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0

# All done, thank you!
li $v0,10 # code for exit
syscall # exit program


    This was the end of today's Introduction!  Hope you enjoyed it and learned something new. I will try to keep things simple and small for the first couple of Assembly Posts. Bye :)

H2
H3
H4
3 columns
2 columns
1 column
5 Comments