#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Register {
RAX,
RCX,
RDX,
RBX,
RSP,
RBP,
RSI,
RDI,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
EAX,
ECX,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI,
}
impl Register {
pub fn offset(&self, is_x64: bool) -> usize {
let reg_size = if is_x64 { 8 } else { 4 };
let index = self.register_index() as usize;
index * reg_size
}
pub fn register_index(&self) -> u8 {
match self {
Register::RAX => 0,
Register::RCX => 1,
Register::RDX => 2,
Register::RBX => 3,
Register::RSP => 4,
Register::RBP => 5,
Register::RSI => 6,
Register::RDI => 7,
Register::R8 => 8,
Register::R9 => 9,
Register::R10 => 10,
Register::R11 => 11,
Register::R12 => 12,
Register::R13 => 13,
Register::R14 => 14,
Register::R15 => 15,
Register::EAX => 0, Register::ECX => 1, Register::EDX => 2, Register::EBX => 3, Register::ESP => 4, Register::EBP => 5, Register::ESI => 6, Register::EDI => 7, }
}
pub fn size(&self, is_x64: bool) -> usize {
let is_32bit_alias = matches!(
self,
Register::EAX
| Register::ECX
| Register::EDX
| Register::EBX
| Register::ESP
| Register::EBP
| Register::ESI
| Register::EDI
);
if is_32bit_alias {
4 } else if is_x64 {
8 } else {
4 }
}
pub fn is_32bit_alias(&self) -> bool {
matches!(
self,
Register::EAX
| Register::ECX
| Register::EDX
| Register::EBX
| Register::ESP
| Register::EBP
| Register::ESI
| Register::EDI
)
}
pub fn all_x64_registers() -> Vec<Register> {
vec![
Register::RAX,
Register::RCX,
Register::RDX,
Register::RBX,
Register::RSP,
Register::RBP,
Register::RSI,
Register::RDI,
Register::R8,
Register::R9,
Register::R10,
Register::R11,
Register::R12,
Register::R13,
Register::R14,
Register::R15,
]
}
pub fn all_x86_registers() -> Vec<Register> {
vec![
Register::EAX,
Register::ECX,
Register::EDX,
Register::EBX,
Register::ESP,
Register::EBP,
Register::ESI,
Register::EDI,
]
}
}
pub fn calculate_storage_size(registers: &[Register], is_x64: bool) -> usize {
if registers.is_empty() {
return 0;
}
let reg_size = if is_x64 { 8 } else { 4 };
16 * reg_size
}