Flecks of Rust #4: Making the Rust compiler emit assembly language

If for some reason you want to see what kind of code the Rust compiler generates, you can easily do that with the --emit command line option.

To try it out, create a new project with Cargo, called helloasm, and change to the directory:

cargo new helloasm
cd helloasm

Then use Cargo to drive the Rust compiler, passing in the necessary flags (separating them from Cargo's flags with --):

cargo rustc -- --emit asm

The generated assembly language can be found in target/debug/deps/helloasm.s. The syntax is AT&T, so if you would rather have it in Intel x86 assembly syntax, pass a configuration to LLVM:

cargo rustc -- --emit asm -C "llvm-args=-x86-asm-syntax=intel"

If you're on an Intel machine, but would like to generate ARM executables (and ARM assembly), first make sure that you have the necessary target(s) installed using rustup show.

% rustup show
    Default host: x86_64-apple-darwin
    rustup home:  /Users/me/.rustup

    installed targets for active toolchain
    --------------------------------------

    x86_64-apple-darwin
    x86_64-unknown-linux-musl

    active toolchain
    ----------------

    stable-x86_64-apple-darwin (default)
    rustc 1.55.0 (c8dfcfe04 2021-09-06)

In this case, the ARM / Apple silicon target is not installed yet. Check out Platform Support in The rustc book, or use rustup target list to see both available and currently installed targets.

For Apple silicon on macOS you should install the target aarch64-apple-darwin (Tier 2 with host support at the time of this writing):

% rustup target add aarch64-apple-darwin
info: downloading component 'rust-std' for 'aarch64-apple-darwin'
info: installing component 'rust-std' for 'aarch64-apple-darwin'
 20.2 MiB /  20.2 MiB (100 %)  14.3 MiB/s in  1s ETA:  0s

Now you can compile for Apple silicon and macOS, and emit ARM assembly language, with:

cargo rustc --target aarch64-apple-darwin -- --emit asm

The result can be found in target/aarch64-apple-darwin/debug/deps.

Use the --release flag if necessary, and replace debug in the path with release.