Include Assembler Source Files In Rust Project (and Build with Cargo)

Published by Philipp Schuster on

Recently I stumbled upon a Rust project, where *.S– and *.rs-files were side by side in the same Cargo src-directory and I was like: “What the heck, I always wanted this!” This was a pure and lucky coincidence, really. If you programmed in C/++ before, you probably know this. The gcc (or to be more specific, the linker) can consume object files generated from *.c or *.S files, where the latter means files written in GAS (GNU Assembler).

When writing firmware or operating systems, it’s important to be able to do this. For example you can construct an aligned multiboot2-header using assembly or initialize the stack and other things before you jump into the code of a higher level language like C or Rust. Whole function definitions also must live in the “global_asm”-space, because inline assembly in Rust is not capable of doing this.

The trick to achieve this in Rust is the experimental and poorly (or better to say, not all at) documented global_asm-feature. It allows you to include assembly as it was in a separate file and compiled along. There is no documentation at all, but due to my findings, it consumes only GAS (GNU Assembler), which requires gcc on your system. Perhaps it uses the default assembly syntax flavor + compiler on Windows, I didn’t tested this.

// works definitely with rustc 1.55-nightly
// Add this in your main.rs or lib.rs

#![feature(global_asm)]


// include_str! copies the file content (written in GNU assembly)
// file path starts relative in "src/" directory
global_asm!(include_str!("gnu_asm.S"));

This is the complete trick. This means that cargo build will also take care of the assembly files. Furthermore, cargo notices if one of these files changed and recompile the necessary parts. I didn’t trace the internal process but I guess it creates a separate object file and links it together with the object files from the files written in Rust.

I made a demo project on Github where you can see the magic in action. This feature requires Rust nightly, at least in July 2021 (Rustc 1.55-nightly). More official info can be found here.


Philipp Schuster

Hi, I'm Philipp and interested in Computer Science. I especially like low level development, making ugly things nice, and de-mystify "low level magic".

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *