exercises

Log | Files | Refs | README

assembly_syscall.rs (1599B)


      1 use std::arch::asm;
      2 
      3 #[inline(never)]
      4 pub fn syscall(message: String) {
      5     let msg_ptr = message.as_ptr();
      6     let len = message.len();
      7 
      8     // We can only call inline assembly using unsafe Rust
      9     unsafe {
     10         asm!(
     11             // The first line of assembly puts the value 1 in the rax register.
     12             // The kernel knows that a value of 1 in the rax means that we
     13             // want to make a `write`.
     14             "mov rax, 1",
     15             // The second line puts the value 1 in the rdi register.
     16             // This tells the kernel where we want to write to.
     17             "mov rdi, 1",
     18             // This calls the syscall instruction. This issues a software
     19             // interrupt, and the CPU passes on control to the OS.
     20             "syscall",
     21             // This writes the address to the buffer where our text is stored
     22             // in the rsi register.
     23             in("rsi") msg_ptr,
     24             // This writes the length (in bytes) of our text buffer to the
     25             // rdx register.
     26             in("rdx") len,
     27             // These four lines are not instructions to the CPU; they're
     28             // meant to tell the compiler that it can't store anything in
     29             // these registers and assume the data is untouched when we
     30             // exit the inline assembly block.
     31             //
     32             // We tell the compiler that there will be some unspecified
     33             // data (indicated by underscore) written to these registers.
     34             out("rax") _,
     35             out("rdi") _,
     36             lateout("rsi") _,
     37             lateout("rdx") _
     38         );
     39     }
     40 }