#[derive(Default, Clone)]
pub struct Registers {
pub rax: u64,
pub rbx: u64,
pub rcx: u64,
pub rdx: u64,
pub rsp: u64,
pub rbp: u64,
pub rsi: u64,
pub rdi: u64,
pub r8: u64,
pub r9: u64,
pub r10: u64,
pub r11: u64,
pub r12: u64,
pub r13: u64,
pub r14: u64,
pub r15: u64,
pub rflags: u64,
pub rip: u64,
pub es: u16,
pub cs: u16,
pub ss: u16,
pub ds: u16,
pub fs: u16,
pub gs: u16,
pub gdtr: u64,
pub ldtr: u64,
pub idtr: u64,
pub fpu: Option<Box<FPU>>,
pub avx: Option<Box<AVX>>,
}
const FLAG_CF: u8 = 0;
const FLAG_PF: u8 = 2;
const FLAG_AF: u8 = 4;
const FLAG_ZF: u8 = 6;
const FLAG_SF: u8 = 7;
const FLAG_DF: u8 = 10;
const FLAG_OF: u8 = 11;
pub const STATUS_MASK: u64 = (1 << FLAG_CF)
| (1 << FLAG_PF)
| (1 << FLAG_AF)
| (1 << FLAG_ZF)
| (1 << FLAG_SF)
| (1 << FLAG_DF)
| (1 << FLAG_OF);
macro_rules! flag {
($index:ident, $get:ident, $set:ident) => {
#[inline]
pub fn $get(&self) -> bool {
(self.rflags & (1 << $index)) > 0
}
#[inline]
pub fn $set(&mut self, is_set: bool) {
if is_set {
self.rflags |= 1 << $index;
} else {
self.rflags &= !(1 << $index);
}
}
};
}
macro_rules! reg {
($reg:ident, $get_64:ident, $get_32:ident, $get_16:ident, $get_8l:ident, $set_64:ident, $set_32:ident, $set_16:ident, $set_8l:ident) => {
#[inline]
pub fn $get_64(&self) -> u64 {
self.$reg
}
#[inline]
pub fn $get_32(&self) -> u32 {
(self.$reg & 0xFFFF_FFFF) as u32
}
#[inline]
pub fn $get_16(&self) -> u16 {
(self.$reg & 0xFFFF) as u16
}
#[inline]
pub fn $get_8l(&self) -> u8 {
(self.$reg & 0xFF) as u8
}
#[inline]
pub fn $set_64(&mut self, value: u64) {
self.$reg = value;
}
#[inline]
pub fn $set_32(&mut self, value: u32) {
self.$reg = value as u64;
}
#[inline]
pub fn $set_16(&mut self, value: u16) {
self.$reg &= 0xFFFF_FFFF_FFFF_0000;
self.$reg |= (value as u64) & 0xFFFF;
}
#[inline]
pub fn $set_8l(&mut self, value: u8) {
self.$reg &= 0xFFFF_FFFF_FFFF_FF00;
self.$reg |= (value as u64) & 0xFF;
}
};
}
macro_rules! regh {
($reg:ident, $get_8h:ident, $set_8h:ident) => {
#[inline]
pub fn $get_8h(&self) -> u8 {
((self.$reg & 0xFF00) >> 8) as u8
}
#[inline]
pub fn $set_8h(&mut self, value: u8) {
self.$reg &= 0xFFFF_FFFF_FFFF_00FF;
self.$reg |= ((value as u64) & 0xFF) << 8;
}
};
}
impl Registers {
reg!(rax, rax, eax, ax, al, set_rax, set_eax, set_ax, set_al);
regh!(rax, ah, set_ah);
reg!(rbx, rbx, ebx, bx, bl, set_rbx, set_ebx, set_bx, set_bl);
regh!(rbx, bh, set_bh);
reg!(rcx, rcx, ecx, cx, cl, set_rcx, set_ecx, set_cx, set_cl);
regh!(rcx, ch, set_ch);
reg!(rdx, rdx, edx, dx, dl, set_rdx, set_edx, set_dx, set_dl);
regh!(rdx, dh, set_dh);
reg!(r8, r8, r8d, r8w, r8b, set_r8, set_r8d, set_r8w, set_r8b);
reg!(r9, r9, r9d, r9w, r9b, set_r9, set_r9d, set_r9w, set_r9b);
reg!(r10, r10, r10d, r10w, r10b, set_r10, set_r10d, set_r10w, set_r10b);
reg!(r11, r11, r11d, r11w, r11b, set_r11, set_r11d, set_r11w, set_r11b);
reg!(r12, r12, r12d, r12w, r12b, set_r12, set_r12d, set_r12w, set_r12b);
reg!(r13, r13, r13d, r13w, r13b, set_r13, set_r13d, set_r13w, set_r13b);
reg!(r14, r14, r14d, r14w, r14b, set_r14, set_r14d, set_r14w, set_r14b);
reg!(r15, r15, r15d, r15w, r15b, set_r15, set_r15d, set_r15w, set_r15b);
reg!(rsi, rsi, esi, si, sil, set_rsi, set_esi, set_si, set_sil);
reg!(rdi, rdi, edi, di, dil, set_rdi, set_edi, set_di, set_dil);
reg!(rsp, rsp, esp, sp, spl, set_rsp, set_esp, set_sp, set_spl);
reg!(rbp, rbp, ebp, bp, bpl, set_rbp, set_ebp, set_bp, set_bpl);
reg!(rip, rip, eip, ip, _ipl_fake, set_rip, set_eip, set_ip, _set_ipl);
flag!(FLAG_CF, cf, set_cf);
flag!(FLAG_PF, pf, set_pf);
flag!(FLAG_AF, af, set_af);
flag!(FLAG_ZF, zf, set_zf);
flag!(FLAG_SF, sf, set_sf);
flag!(FLAG_DF, df, set_df);
flag!(FLAG_OF, of, set_of);
pub fn es(&self) -> u16 {
self.es
}
pub fn cs(&self) -> u16 {
self.cs
}
pub fn ss(&self) -> u16 {
self.ss
}
pub fn ds(&self) -> u16 {
self.ds
}
pub fn fs(&self) -> u16 {
self.fs
}
pub fn gs(&self) -> u16 {
self.gs
}
#[inline]
pub fn rflags(&self) -> u64 {
self.rflags
}
}
#[derive(Default, Clone)]
pub struct FPU {
pub st0: f64,
pub st1: f64,
pub st2: f64,
pub st3: f64,
pub st4: f64,
pub st5: f64,
pub st6: f64,
pub st7: f64,
pub x87control: u64,
pub x87status: u64,
pub x87tag: u64,
}
#[derive(Default, Clone)]
pub struct AVX {
pub zmm0: [u8; 32],
pub zmm1: [u8; 32],
pub zmm2: [u8; 32],
pub zmm3: [u8; 32],
pub zmm4: [u8; 32],
pub zmm5: [u8; 32],
pub zmm6: [u8; 32],
pub zmm7: [u8; 32],
pub zmm8: [u8; 32],
pub zmm9: [u8; 32],
pub zmm10: [u8; 32],
pub zmm11: [u8; 32],
pub zmm12: [u8; 32],
pub zmm13: [u8; 32],
pub zmm14: [u8; 32],
pub zmm15: [u8; 32],
pub zmm16: [u8; 32],
pub zmm17: [u8; 32],
pub zmm18: [u8; 32],
pub zmm19: [u8; 32],
pub zmm20: [u8; 32],
pub zmm21: [u8; 32],
pub zmm22: [u8; 32],
pub zmm23: [u8; 32],
pub zmm24: [u8; 32],
pub zmm25: [u8; 32],
pub zmm26: [u8; 32],
pub zmm27: [u8; 32],
pub zmm28: [u8; 32],
pub zmm29: [u8; 32],
pub zmm30: [u8; 32],
pub zmm31: [u8; 32],
}