System calls, FFI, and cross-platform abstractions 53 First, we have an attribute named #[inline(never)] that tells the compiler that we never want this function to be inlined during optimization. Inlining is when the compiler omits the function call and simply copies the body of the function instead of calling it. In this case, we don't want that to ever happen. Next, we have our function call. The first two lines in the function simply get the raw pointer to the memory location where our text is stored and the length of the text buffer. The next line is an unsafe block since there is no way to call assembly such as this safely in Rust. The first line of assembly puts the value 1 in the rax register. When the CPU traps our call later on and passes control to the OS, the kernel knows that a value of one in rax means that we want to make a write. The second line puts the value 1 in the rdi register. This tells the kernel where we want to write to, and a value of one means that we want to write to stdout. The third line calls the syscall instruction. This instruction issues a software interrupt, and the CPU passes on control to the OS. Rust's inline assembly syntax will look a little intimidating at first, but bear with me. We'll cover this in detail a little later in this book so that you get comfortable with it. For now, I'll just briefly explain what it does. The fourth line writes the address to the buffer where our text is stored in the rsi register. The fifth line writes the length (in bytes) of our text buffer to the rdx register. The next four lines are not instructions to the CPU; they're meant to tell the compiler that it can't store anything in these registers and assume the data is untouched when we exit the inline assembly block. We do that by telling the compiler that there will be some unspecified data (indicated by the underscore) written to these registers. Finally, it's time to call our raw syscall: fn main() { let message = "Hello world from raw syscall!\n"; let message = String::from(message); syscall(message); } This function simply creates a String and calls our syscall function, passing it in as an argument.