Chapter 6 - Subprograms
We have now covered the basics of programming in assembly code. Many a times, we might have to repeat the same code in the program and that is where we use functions in languages like C. Let's see how it is done in assembly language.
The concept of subprograms can be used heavily in assembly language, since input and output operations require more than one line of code. Making them into subprograms not only makes the code smaller, but also helps you understand and debug the code better. It is highly reccommended that you start using subprograms in your code from the very start of programming in assembly language.
CALL & RET Statements
In NASM subprograms are implemented using the call and ret instructions. The general syntax is as follows:
;main code....
-------------
-------------
call function_name
-------------
-------------
;rest of the code....
function_name: ;Label for subprogram
----------
----------
;function code....
----------
----------
ret
- When we use the CALL instruction, address of the next instruction will be copied to the system stack and it will jump to the subprogram. ie. ESP will be decreased by 4 units and address of the next instruction will go over there.
- When we call the ret towards the end of the sub-program then the address being pushed to the top of the stack will be restored and control will jump to that
Calling Conventions
The set of rules that the calling program and the subprogram should obey to pass parameters are called calling conventions. Calling conventions allow a subprogram to be called at various parts of the code with different data to operate on. The data may be passed using system registers / memory variables / system stack. If we are using system stack, parameters should be pushed to system stack before the CALL statement and remember to pop off, preserve and to push back the return address within the sub program which will be in the top of the stack.
NB: One major advantage of subprograms that you can exploit is by creating subprograms for input and output, as they are two code components which appear in almost all the programs you are going to write. As the codes are quite lengthy, repeating the code for each input and output will make your code even lengthier, making debugging and understanding the code a tedious task. In the program given below, three subprograms are used, one for input, one for output and the last one for calculating the sum. It is suggested that you use subprograms for input and ouput from now on.
Now, let's see an example on how to use subprograms effectively to simplify your code. Below is a program which uses subprograms to calculate the sum of 10 input integers.
Recursive Sub-routine
A subprogram which calls itself again and again recursively to calculate the return value is called recursive sub-routine. We could implement recursive sub-routine for operations like calculating factorial of a number very easily in NASM. A program to print fibonacci series up to a number using recursive subprogram is given in the appendix.
Using C Library functions in NASM
We can embed standard C library functions into our NASM Program especially for I/O operations. If we would like to use that then we have to follow C’s calling conventions given below:
-
Parameters are passed to the system stack from left to right order.
Eg:
printf(“\%d”,x)
Here value of x must be pushed to system stack and then the format string.
-
C-Function won’t pop out the parameters automatically, so it is our duty to restore the status of stack pointers(ESP and EBP) after the function being called.
Example: Reading an integer using the C-Functions
Assembling and executing the code
First we have to assemble the code to object code with NASM Assembler, then we have to use gcc compiler to make the executable code.
- nasm -f elf -o int.o int.asm
- gcc int.o -o int
- ./int