Assembler is not a “structured language.” Look at the multitude of jmp instructions and labels that allow the program execution to jump around and back and forth. Modern high-level programming languages have structures such as do...while, while...do, case, and so on. This is not so with assembly language.
But similar to modern program languages, assembly language has functions and procedures to help you give your code more structure. A little bit of nit-picking: a function executes instructions and returns a value. A procedure executes instructions and does not return a value.
In this book, we have already used functions; that is, we used an external function called printf , which is a C library function. In this chapter, we will introduce simple functions; in later chapters, we will cover important aspects of functions such as stack alignment, external functions, and calling conventions.
Writing a Simple Function
function.asm
There is a main part, identified as before with the label main, and then there is a function, identified with the label area. In main, the function area is called, which calculates the area of a circle using radius and pi, which are variables stored in a location in memory. As you can see, functions must have a prologue and an epilogue, similar to main.
The computed area is stored in xmm0. Returning from the function to main, printf is called with rax containing the value 1, meaning there is one xmm register that needs to be printed. We introduce a new instruction here: leave. This instruction does the same as mov rsp, rbp, and pop rbp (the epilogue).
If you return a value from a function, you use xmm0 for floating-point values and use rax for other values, such as integers or addresses. The function arguments, pi and radius, are located in memory. That is okay for now, but it is better to use registers and the stack to store function arguments. Using memory variables to pass on values to functions can create naming conflicts between values used in main and in functions and can make your code less “portable.”
More Functions
function2.asm
Here, we have main calling the function circle, which in turn calls the functions area and circum. So, functions can call other functions. In fact, main is just a function calling other functions. But beware that functions cannot be nested, which means functions cannot contain the code for other functions.
Also, functions can have their own sections, such as .data, .bss, and .text. What about the period before pi and the fmt variables? The period indicates a local variable, which means that the variable is known only inside the function where it is declared. In the function area, we used a value for pi that is different from the pi used in the function circum. The variable radius, declared in section .data of main, is known in every function in this source code listing, including main. It is always advisable to use local variables whenever possible; this reduces the risk of conflicting variable names.
Summary
How to use functions.
Functions can have their own section .data and section .bss.
Functions cannot be nested.
Functions can call other functions.
main is just another function.
How to use local variables.