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