From 11afe73e7f0db146ea096c6c317fe781beb5f191 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 3 Jul 2021 17:49:31 -0700 Subject: write some dang docs, export `MemoryAccessSize` where you'll look for it --- src/lib.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 1be1e7f..cb879fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,66 @@ +//! # `yaxpeax-x86`, a decoder for x86-family instruction sets +//! +//! `yaxpeax-x86` provides x86 decoders, for 64-, 32-, and 16-bit modes. `yaxpeax-x86` also +//! implements traits defined by `yaxpeax_arch`, making it suitable for interchangeable use with +//! other `yaxpeax`-family instruction decoders. +//! +//! ## usage +//! +//! the fastest way to decode an x86 instruction is through [`amd64::InstDecoder::decode_slice()`]: +//! ``` +//! let decoder = yaxpeax_x86::amd64::InstDecoder::default(); +//! +//! let inst = decoder.decode_slice(&[0x33, 0xc0]).unwrap(); +//! +//! assert_eq!("xor eax, eax", inst.to_string()); +//! ``` +//! +//! instructions, operands, registers, and generally all decoding structures, are in their mode's +//! repsective submodule: +//! * `x86_64`/`amd64` decoding is under [`yaxpeax_x86::long_mode`] +//! * `x86_32`/`x86` decoding is under [`yaxpeax_x86::protected_mode`] +//! * `x86_16`/`8086` decoding is under [`yaxpeax_x86::real_mode`] +//! +//! all modes have equivalent data available in a decoded instruction. for example, all modes have +//! library-friendly `Operand` and `RegSpec` types: +//! +//! ``` +//! use yaxpeax_x86::amd64::{InstDecoder, Operand, RegSpec}; +//! +//! let decoder = yaxpeax_x86::amd64::InstDecoder::default(); +//! +//! let inst = decoder.decode_slice(&[0x33, 0x01]).unwrap(); +//! +//! assert_eq!("xor eax, dword [rcx]", inst.to_string()); +//! +//! assert_eq!(Operand::Register(RegSpec::eax()), inst.operand(0)); +//! assert_eq!("eax", inst.operand(0).to_string()); +//! assert_eq!(Operand::RegDeref(RegSpec::rcx()), inst.operand(1)); +//! +//! // an operand in isolation does not know the size of memory it references, if any +//! assert_eq!("[rcx]", inst.operand(1).to_string()); +//! +//! // and for memory operands, the size must be read from the instruction itself: +//! let mem_size: yaxpeax_x86::amd64::MemoryAccessSize = inst.mem_size().unwrap(); +//! assert_eq!("dword", mem_size.size_name()); +//! +//! // `MemoryAccessSize::size_name()` is how its `Display` impl works, as well: +//! assert_eq!("dword", mem_size.to_string()); +//! ``` +//! +//! ## `#![no_std]` +//! +//! `yaxpeax-x86` supports `no_std` usage. to be built `no_std`, `yaxpeax-x86` only needs +//! `default-features = false` in the corresponding `Cargo.toml` dependency. if formatting is +//! needed with `std` disabled, it can be re-enabled by explicitly requesting the `fmt` features +//! like: +//! ```text +//! yaxpeax-x86 = { version = "*", default-features = false, features = ["fmt"] } +//! ``` +//! +//! this is how the `.so` and `.a` packaging in +//! [`ffi/`](https://github.com/iximeow/yaxpeax-x86/tree/no-gods-no-/ffi) is performed. + #![no_std] #[cfg(feature="use-serde")] @@ -47,3 +110,10 @@ impl MemoryAccessSize { MEM_SIZE_STRINGS[self.size as usize - 1] } } + +#[cfg(feature = "fmt")] +impl core::fmt::Display for MemoryAccessSize { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.write_str(self.size_name()) + } +} -- cgit v1.1