use crate::*;
const DATA_ADDR: u64 = 0x7000;
#[test]
fn test_push_imm8_zero() {
let code = [
0x6a, 0x00, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x0FF8, "RSP decremented by 8");
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0, "Zero pushed");
}
#[test]
fn test_push_imm8_positive_small() {
let code = [
0x6a, 0x01, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 1, "Small positive value");
}
#[test]
fn test_push_imm8_positive_medium() {
let code = [
0x6a, 0x42, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0x42, "Medium positive value");
}
#[test]
fn test_push_imm8_max_positive() {
let code = [
0x6a, 0x7f, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 127, "Max positive 8-bit signed");
}
#[test]
fn test_push_imm8_negative_one() {
let code = [
0x6a, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFF, "-1 sign-extended to 64-bit");
}
#[test]
fn test_push_imm8_negative_small() {
let code = [
0x6a, 0xfe, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFE, "-2 sign-extended");
}
#[test]
fn test_push_imm8_negative_medium() {
let code = [
0x6a, 0xf0, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFF0, "-16 sign-extended");
}
#[test]
fn test_push_imm8_min_negative() {
let code = [
0x6a, 0x80, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFF80, "-128 sign-extended");
}
#[test]
fn test_push_imm8_boundary_values() {
let code = [
0x6a, 0x7f, 0x6a, 0x80, 0x6a, 0x00, 0x6a, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000 - 32, "Four values pushed");
assert_eq!(emu.maps.read_qword(0x1000 - 8).unwrap(), 127, "First push");
assert_eq!(
emu.maps.read_qword(0x1000 - 16).unwrap(),
0xFFFFFFFFFFFFFF80,
"Second push"
);
assert_eq!(emu.maps.read_qword(0x1000 - 24).unwrap(), 0, "Third push");
assert_eq!(
emu.maps.read_qword(0x1000 - 32).unwrap(),
0xFFFFFFFFFFFFFFFF,
"Fourth push"
);
}
#[test]
fn test_push_imm32_zero() {
let code = [
0x68, 0x00, 0x00, 0x00, 0x00, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x0FF8, "RSP decremented by 8");
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0, "Zero pushed");
}
#[test]
fn test_push_imm32_small_positive() {
let code = [
0x68, 0x01, 0x00, 0x00, 0x00, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 1, "Small positive value");
}
#[test]
fn test_push_imm32_medium_positive() {
let code = [
0x68, 0x78, 0x56, 0x34, 0x12, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0x12345678, "Medium positive value");
}
#[test]
fn test_push_imm32_large_positive() {
let code = [
0x68, 0xff, 0xff, 0xff, 0x7f, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0x7FFFFFFF, "Max positive 32-bit signed");
}
#[test]
fn test_push_imm32_negative_one() {
let code = [
0x68, 0xff, 0xff, 0xff, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFF, "-1 sign-extended");
}
#[test]
fn test_push_imm32_negative_small() {
let code = [
0x68, 0xfe, 0xff, 0xff, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFE, "-2 sign-extended");
}
#[test]
fn test_push_imm32_negative_large() {
let code = [
0x68, 0x00, 0x00, 0x00, 0x80, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFF80000000, "Min 32-bit signed extended");
}
#[test]
fn test_push_imm32_pattern_deadbeef() {
let code = [
0x68, 0xef, 0xbe, 0xad, 0xde, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFDEADBEEF, "0xDEADBEEF sign-extended");
}
#[test]
fn test_push_imm32_pattern_cafebabe() {
let code = [
0x68, 0xbe, 0xba, 0xfe, 0xca, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFCAFEBABE, "0xCAFEBABE sign-extended");
}
#[test]
fn test_push_imm8_sequence() {
let code = [
0x6a, 0x01, 0x6a, 0x02, 0x6a, 0x03, 0x6a, 0x04, 0x6a, 0x05, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000 - 40, "Five values pushed");
assert_eq!(
emu.maps.read_qword(emu.regs().rsp).unwrap(),
5,
"Top of stack"
);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 8).unwrap(), 4);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 16).unwrap(), 3);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 24).unwrap(), 2);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 32).unwrap(), 1);
}
#[test]
fn test_push_imm32_sequence() {
let code = [
0x68, 0x01, 0x00, 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x00, 0x68, 0x03, 0x00, 0x00, 0x00, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000 - 24, "Three values pushed");
assert_eq!(emu.maps.read_qword(emu.regs().rsp).unwrap(), 3);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 8).unwrap(), 2);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 16).unwrap(), 1);
}
#[test]
fn test_push_imm_mixed_sizes() {
let code = [
0x6a, 0x11, 0x68, 0x22, 0x22, 0x22, 0x22, 0x6a, 0x33, 0x68, 0x44, 0x44, 0x44, 0x44, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000 - 32, "Four values pushed");
assert_eq!(emu.maps.read_qword(0x1000 - 32).unwrap(), 0x44444444);
assert_eq!(emu.maps.read_qword(0x1000 - 24).unwrap(), 0x33);
assert_eq!(emu.maps.read_qword(0x1000 - 16).unwrap(), 0x22222222);
assert_eq!(emu.maps.read_qword(0x1000 - 8).unwrap(), 0x11);
}
#[test]
fn test_push_imm8_pop_roundtrip() {
let code = [
0x6a, 0x42, 0x58, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x42, "Value popped into RAX");
assert_eq!(emu.regs().rsp, 0x1000, "Stack balanced");
}
#[test]
fn test_push_imm32_pop_roundtrip() {
let code = [
0x68, 0x78, 0x56, 0x34, 0x12, 0x58, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0x12345678, "Value popped into RAX");
assert_eq!(emu.regs().rsp, 0x1000, "Stack balanced");
}
#[test]
fn test_push_imm_negative_pop() {
let code = [
0x6a, 0xff, 0x58, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xFFFFFFFFFFFFFFFF, "-1 in RAX");
}
#[test]
fn test_push_imm_preserves_registers() {
let code = [
0x48, 0xc7, 0xc0, 0xaa, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc3, 0xbb, 0x00, 0x00, 0x00, 0x6a, 0x42, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 0xAA, "RAX unchanged");
assert_eq!(emu.regs().rbx, 0xBB, "RBX unchanged");
}
#[test]
fn test_push_imm_preserves_flags() {
let code = [
0xf9, 0x6a, 0x42, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_ne!(emu.flags().dump() & 0x01, 0, "CF preserved");
}
#[test]
fn test_push_imm_function_params() {
let code = [
0x6a, 0x03, 0x6a, 0x02, 0x6a, 0x01, 0x48, 0x83, 0xc4, 0x18, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x1000, "Stack cleaned up");
}
#[test]
fn test_push_imm_large_params() {
let code = [
0x68, 0x00, 0x10, 0x00, 0x00, 0x68, 0x00, 0x20, 0x00, 0x00, 0x68, 0x00, 0x30, 0x00, 0x00, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x2000-(0x2000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x2000;
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(emu.regs().rsp).unwrap(), 0x3000);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 8).unwrap(), 0x2000);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 16).unwrap(), 0x1000);
}
#[test]
fn test_push_imm8_all_ones() {
let code = [
0x6a, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFF, "All ones");
}
#[test]
fn test_push_imm32_all_ones() {
let code = [
0x68, 0xff, 0xff, 0xff, 0xff, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFFFFFFFFFF, "All ones");
}
#[test]
fn test_push_imm_at_low_stack() {
let code = [
0x6a, 0x42, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x10-(0x10 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x10;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x08, "RSP at low address");
let val = emu.maps.read_qword(0x08).unwrap();
assert_eq!(val, 0x42, "Value pushed");
}
#[test]
fn test_push_imm_rapid_sequence() {
let code = [
0x6a, 0x00, 0x6a, 0x01, 0x6a, 0x02, 0x6a, 0x03, 0x6a, 0x04, 0x6a, 0x05, 0x6a, 0x06, 0x6a,
0x07, 0x6a, 0x08, 0x6a, 0x09, 0x6a, 0x0a, 0x6a, 0x0b, 0x6a, 0x0c, 0x6a, 0x0d, 0x6a, 0x0e,
0x6a, 0x0f, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x2000-(0x2000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x2000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rsp, 0x2000 - 128, "16 values pushed");
for i in 0..16 {
let val = emu.maps.read_qword(emu.regs().rsp + i * 8).unwrap();
assert_eq!(val, 15 - i, "Value at position {}", i);
}
}
#[test]
fn test_push_imm32_alternating_bits() {
let code = [
0x68, 0x55, 0x55, 0x55, 0x55, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0x55555555, "Alternating bits");
}
#[test]
fn test_push_imm32_inverse_alternating() {
let code = [
0x68, 0xaa, 0xaa, 0xaa, 0xaa, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(
val, 0xFFFFFFFFAAAAAAAA,
"Inverse alternating (sign-extended)"
);
}
#[test]
fn test_push_imm32_high_bit_set() {
let code = [
0x68, 0x00, 0x00, 0x00, 0x80, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0xFFFFFFFF80000000, "High bit triggers sign extension");
}
#[test]
fn test_push_imm32_high_bit_clear() {
let code = [
0x68, 0xff, 0xff, 0xff, 0x7f, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
let val = emu.maps.read_qword(0x0FF8).unwrap();
assert_eq!(val, 0x7FFFFFFF, "High bit clear, no sign extension");
}
#[test]
fn test_push_imm_powers_of_two() {
let code = [
0x6a, 0x01, 0x6a, 0x02, 0x6a, 0x04, 0x6a, 0x08, 0x6a, 0x10, 0x6a, 0x20, 0x6a, 0x40, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(emu.regs().rsp).unwrap(), 64);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 8).unwrap(), 32);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 16).unwrap(), 16);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 24).unwrap(), 8);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 32).unwrap(), 4);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 40).unwrap(), 2);
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 48).unwrap(), 1);
}
#[test]
fn test_push_imm_ascii_values() {
let code = [
0x6a, 0x41, 0x6a, 0x42, 0x6a, 0x43, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(emu.regs().rsp).unwrap(), 0x43, "'C'");
assert_eq!(
emu.maps.read_qword(emu.regs().rsp + 8).unwrap(),
0x42,
"'B'"
);
assert_eq!(
emu.maps.read_qword(emu.regs().rsp + 16).unwrap(),
0x41,
"'A'"
);
}
#[test]
fn test_push_imm_boolean_values() {
let code = [
0x6a, 0x00, 0x6a, 0x01, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.maps.read_qword(emu.regs().rsp).unwrap(), 1, "true");
assert_eq!(emu.maps.read_qword(emu.regs().rsp + 8).unwrap(), 0, "false");
}
#[test]
fn test_push_imm_then_add() {
let code = [
0x6a, 0x05, 0x58, 0x48, 0x83, 0xc0, 0x03, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 8, "5 + 3 = 8");
}
#[test]
fn test_push_imm_multiple_ops() {
let code = [
0x6a, 0x0a, 0x6a, 0x05, 0x58, 0x5b, 0x48, 0x01, 0xd8, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 15, "5 + 10 = 15");
}
#[test]
fn test_push_imm_stack_based_calc() {
let code = [
0x6a, 0x03, 0x6a, 0x04, 0x6a, 0x05, 0x59, 0x5b, 0x58, 0x48, 0x0f, 0xaf, 0xc3, 0x48, 0x01, 0xc8, 0xf4, ];
let mut emu = emu64();
emu.load_code_bytes(&code);
emu.maps.create_map("stack_test", 0x1000-(0x1000 / 2), 0x1000, crate::maps::mem64::Permission::READ_WRITE_EXECUTE).unwrap();
emu.regs_mut().rsp = 0x1000;
emu.run(None).unwrap();
assert_eq!(emu.regs().rax, 17, "3 * 4 + 5 = 17");
}