How to mix GNU Assembly and C

Each programming language has its own pros and cons like Assembly is faster than C (Modern compilers can generate more efficient codes but not all the time) or C is portable while assembly is not. I mostly use C language to program microcontrollers but what if I need some features of Assembly language?

I have written my own RTOS for STM32 microcontrollers which has arm cortex M3 core by using C language. When it came up to write scheduler that needs context switch operation, I could not do it by using C. Basically, i needed to to store register values in corresponding stacks for each task when scheduler runs. It is not possible to work on register level in C language.

-Should I move to Assembly from C?

-If yes, then I will be deprived of C language features and it is going to be challenging to write whole kernel in assembly.

Best solution is using both together. There are different scenarios to mix them. In this article, i will explain exporting from assembly to C, exporting from C to assembly and inline assembly usage.

Let’s start with inline assembly, we can directly put our assembly code into C source file thanks to inline assembly.

Inline assembly

/* Includes */
#include "stm32f10x.h"


int var1=0;
int main(void)
{

	asm
        (
	       "    LDR r0,=var1   \n"
	       "    LDR R1,[R0]	   \n"
               "    ADD R1,#1      \n"
               "    STR R1,[R0]    \n"
        );

	/* Infinite loop */
	while (1)
	{

	}
}

On code which is given above, you can see syntax of inline assembly usage. Basically, it increments a variable which is called “var1”. Also equivalent C code is giving below.

/* Includes */
#include "stm32f10x.h"


int var1=0;
int main(void)
{
    var1++;

	/* Infinite loop */
    while (1)
    {
    }
}

As we have seen assembly code can be put into C source file directly by using inline assembly syntax. Now let’s declare a function in assembly file and call it from a C course file.

Exporting from Assembly to C

We will write a function which will take one argument and return it after incrementing by 1. We will see how to pass an argument and return a value with this example. This example will consist of two files. These are main.c and my_func.s .

main.c

/* Includes */
#include "stm32f10x.h"

extern int increment(int input_var)
int result=0;
int main(void)
{
    result=increment(5);   
	/* Infinite loop */
    while (1)
    {
    }
}

my_func.s

.global increment
.text

    increment:
	ADD R0,#1
	BX  LR

.global assembly directive is used to make increment label visible from other source files. Also extern keyword is used in C file to say linker that we declared this function somewhere else.

Input arguments are put to registers automatically. input_var variable is put to R0 directly if you have more input arguments they will be located into other registers consequently. And finally when we return from label by BX instruction, content of R0 register is returned automatically.

Exporting from C to Assembly

Now we will call a C function from an assembly file. In order to demonstrate this we will use previous method too. Basically, we will invoke an assembly label on a C source file and this assembly label will call another C function.

main.c

/* Includes */
#include "stm32f10x.h"


extern int increment(int a);
int result;
int var1=0;
void var1_increment(void);
int main(void)
{
    result=increment(126);

	/* Infinite loop */
    while (1)
    {
    }
}

void var1_increment(void)
{
    var1++;
}

“increment” function is exported from assembly to C while “var1_increment” function is exported from C to assembly.

my_func.s


.global increment
.extern var1_increment
.text

    increment:
	ADD R0,#1
	BL  var1_increment
	BX  LR

It is better to take note that I tired to explain general idea and show basic syntax.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s