In the previous chapters, we used C functions from time to time for convenience, such as the standard printf function or the version we developed, printb. In this chapter, we will show how to use assembler functions in the programming language C. The value of the calling conventions will become immediately evident. In this chapter, we use the System V AMD64 ABI calling conventions, because we are working on a Linux operating system. Windows has different calling conventions. If you have worked your way through the previous chapters and example code, this chapter will be an easy one.
Writing the C Source File
Most of the assembler code should be familiar to you from previous chapters. Just the C program is new. We compute the area and circumference of a rectangle and a circle. Then we take a string and reverse it, and finally we take the sum of the elements of an array, double the elements of the array, and take the sum of the elements of the doubled array. Let’s look at the different source files.
fromc.c.asm
Writing the Assembler Code
We start with the function declarations for the assembler functions. These are external functions, and we declare the datatypes of the return values and arguments.
The program will prompt the user for most of the data to be used, except for the array, where we provide some values for convenience.
rect.asm
circle.asm
sreverse.asm
asum.asm
adouble.asm
makefile
In the assembly code, there is nothing special; just be careful about the datatypes of the variables received from the calling C program. The assembly functions take the arguments from the calling program and store them in the registers according to the calling conventions. Results are returned to the caller in rax (integer value) or xmm0 (floating-point value). Now you can develop your own libraries of functions to use in assembler or C, and because of the calling conventions, you do not have to worry about how to pass arguments. Just be careful about using the correct datatypes.
Note how we used a backslash () in the makefile for splitting a long line, and we used tabs to align the instructions.
Summary
Calling an assembly function from within a higher language source, in this case from within C
The value of a calling convention