x86_64/instructions/
mod.rs

1#![cfg(all(feature = "instructions", target_arch = "x86_64"))]
2
3//! Special x86_64 instructions.
4
5pub mod interrupts;
6pub mod port;
7pub mod random;
8pub mod segmentation;
9pub mod smap;
10pub mod tables;
11pub mod tlb;
12
13use core::arch::asm;
14
15/// Halts the CPU until the next interrupt arrives.
16#[inline]
17pub fn hlt() {
18    unsafe {
19        asm!("hlt", options(nomem, nostack, preserves_flags));
20    }
21}
22
23/// Executes the `nop` instructions, which performs no operation (i.e. does nothing).
24///
25/// This operation is useful to work around the LLVM bug that endless loops are illegally
26/// optimized away (see [the issue](https://github.com/rust-lang/rust/issues/28728)). By invoking this
27/// instruction (which is marked as volatile), the compiler should no longer optimize the
28/// endless loop away.
29#[inline]
30pub fn nop() {
31    unsafe {
32        asm!("nop", options(nomem, nostack, preserves_flags));
33    }
34}
35
36/// Emits a '[magic breakpoint](https://wiki.osdev.org/Bochs#Magic_Breakpoint)'
37/// instruction for the [Bochs](http://bochs.sourceforge.net/) CPU
38/// emulator.
39///
40/// Make sure to set `magic_break: enabled=1` in your `.bochsrc` file.
41#[inline]
42pub fn bochs_breakpoint() {
43    unsafe {
44        asm!("xchg bx, bx", options(nomem, nostack, preserves_flags));
45    }
46}
47
48/// Gets the current instruction pointer. Note that this is only approximate as it requires a few
49/// instructions to execute.
50#[inline(always)]
51pub fn read_rip() -> crate::VirtAddr {
52    let rip: u64;
53    unsafe {
54        asm!("lea {}, [rip]", out(reg) rip, options(nostack, nomem, preserves_flags));
55    }
56    crate::VirtAddr::new(rip)
57}