Calling assembly functions from C¶
It is often useful to write code at the lower level of abstraction provided by assembly and then call it from a C program. For example, you might be performance tuning a situation where the compiler isn’t producing adequate assembly from your high-level code, or, more likely, you would like to exploit hardware characteristics that aren’t represented at the higher level. To make the assembly callable from C, the most important aspect is to make sure that they are using compatible calling conventions. Then, it is good practice to provide a C declaration of your assembly function, in a header file. With that, the C code shouldn’t even know any different!
The way to define a function in assembly that can be linked into C code
is actually what we’ve already seen many times with various main
functions, except you can pick a name other than main
! For example,
here is an assembly function that takes two quadword parameters and returns
their difference.
.intel_syntax noprefix
.text
.global sillysub
sillysub:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov QWORD PTR [rbp-16], rsi
mov rax, QWORD PTR [rbp-8]
sub rax, QWORD PTR [rbp-16]
pop rbp
ret
In order to use this function from C, give it a declaration in a C header
just as though it were any other C function. For example, you might have
a file named sillysub.h
with the following contents.
#ifndef SILLYSUB_H
#define SILLYSUB_H
long sillysub(long a, long b);
#endif
Then you can call the function in C code the usual way, like
sillysub(7, 4)
to compute \(7 - 4\).