dynasmrt/
x86.rs

1//! Runtime support for the x86 architecture assembling target.
2//!
3//! The x86 instruction set features variable-length instructions and
4//! relative relocations up to 16 bits in size, or absolute relocations of 32 bits in size.
5//!
6//! The core relocation behaviour for this architecture is provided by the [`X86Relocation`] type.
7//!
8//! Next to that, this module contains the following:
9//!
10//! ## Type aliases
11//!
12//! Several specialized type aliases of the generic [`Assembler`] are provided as these are by far the most common usecase.
13//!
14//! ## Enums
15//!
16//! There are enumerator of every logically distinct register family usable in x86. 
17//! These enums implement the [`Register`] trait and their discriminant values match their numeric encoding in dynamic register literals.
18//!
19//! *Note: The presence of some registers listed here is purely what is encodable. Check the relevant architecture documentation to find what is architecturally valid.*
20
21
22use crate::Register;
23use crate::relocations::SimpleRelocation;
24
25
26/// The x86 architecure doesn't have special relocation encodings.
27pub type X86Relocation = SimpleRelocation;
28
29
30/// An x86 Assembler. This is aliased here for backwards compatability.
31pub type Assembler = crate::Assembler<X86Relocation>;
32/// An x86 AssemblyModifier. This is aliased here for backwards compatability.
33pub type AssemblyModifier<'a> = crate::Modifier<'a, X86Relocation>;
34/// An x86 UncommittedModifier. This is aliased here for backwards compatability.
35pub type UncommittedModifier<'a> = crate::UncommittedModifier<'a>;
36
37
38/// 1, 2 or 4-byte general purpose "double-word" registers.
39///
40/// EIP does not appear here as it cannot be addressed dynamically.
41#[allow(missing_docs)]
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43pub enum Rd {
44    EAX = 0x00, ECX = 0x01, EDX = 0x02, EBX = 0x03,
45    ESP = 0x04, EBP = 0x05, ESI = 0x06, EDI = 0x07,
46}
47reg_impls!(Rd);
48
49/// High-byte general purpose registers.
50#[allow(missing_docs)]
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
52pub enum Rh {
53    AH = 0x4, CH = 0x5, DH = 0x6, BH = 0x7,
54}
55reg_impls!(Rh);
56
57/// 10-byte floating point registers.
58#[allow(missing_docs)]
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
60pub enum Rf {
61    ST0 = 0x0, ST1 = 0x1, ST2 = 0x2, ST3 = 0x3,
62    ST4 = 0x4, ST5 = 0x5, ST6 = 0x6, ST7 = 0x7,
63}
64reg_impls!(Rf);
65
66/// 8-byte MMX registers.
67#[allow(missing_docs)]
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69pub enum Rm {
70    MMX0 = 0x0, MMX1 = 0x1, MMX2 = 0x2, MMX3 = 0x3,
71    MMX4 = 0x4, MMX5 = 0x5, MMX6 = 0x6, MMX7 = 0x7,
72}
73reg_impls!(Rm);
74
75/// 16 or 32-byte SSE registers.
76#[allow(missing_docs)]
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
78pub enum Rx {
79    XMM0  = 0x0, XMM1  = 0x1, XMM2  = 0x2, XMM3  = 0x3,
80    XMM4  = 0x4, XMM5  = 0x5, XMM6  = 0x6, XMM7  = 0x7,
81}
82reg_impls!(Rx);
83
84/// 2-byte segment registers.
85#[allow(missing_docs)]
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
87pub enum Rs {
88    ES = 0x0, CS = 0x1, SS = 0x2, DS = 0x3,
89    FS = 0x4, GS = 0x5,
90}
91reg_impls!(Rs);
92
93/// 4-byte control registers.
94#[allow(missing_docs)]
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
96pub enum RC {
97    CR0  = 0x0, CR1  = 0x1, CR2  = 0x2, CR3  = 0x3,
98    CR4  = 0x4, CR5  = 0x5, CR6  = 0x6, CR7  = 0x7,
99}
100reg_impls!(RC);
101
102/// 4-byte debug registers.
103#[allow(missing_docs)]
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
105pub enum RD {
106    DR0  = 0x0, DR1  = 0x1, DR2  = 0x2, DR3  = 0x3,
107    DR4  = 0x4, DR5  = 0x5, DR6  = 0x6, DR7  = 0x7,
108    DR8  = 0x8, DR9  = 0x9, DR10 = 0xA, DR11 = 0xB,
109    DR12 = 0xC, DR13 = 0xD, DR14 = 0xE, DR15 = 0xF,
110}
111reg_impls!(RD);
112
113/// 16-byte bound registers.
114#[allow(missing_docs)]
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116pub enum RB {
117    BND0 = 0x0, BND1 = 0x1, BND2 = 0x2, BND3 = 0x3
118}
119reg_impls!(RB);
120
121#[cfg(test)]
122mod tests {
123    use super::Rd::*;
124    use crate::Register;
125
126    #[test]
127    fn reg_code() {
128        assert_eq!(EAX.code(), 0);
129    }
130
131    #[test]
132    fn reg_code_from() {
133        assert_eq!(u8::from(ECX), 1);
134    }
135}