move x86_64 bin test
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
use crate::{
|
||||
arch::x86_64::*,
|
||||
backend::{Instr as BInstr, Program},
|
||||
};
|
||||
use std::{fs::OpenOptions, io::Write, os::unix::fs::OpenOptionsExt, process::Command};
|
||||
|
||||
pub fn run() {
|
||||
let mut program = Program::<X86_64>::default();
|
||||
let text = b"Hello world!\n";
|
||||
let text_sym = program.ro_data(text);
|
||||
let entry = program.func([BInstr::Asm(Asm {
|
||||
instrs: vec![
|
||||
mov(ax, 1),
|
||||
mov(di, 1),
|
||||
lea(rsi, text_sym),
|
||||
mov(dx, text.len() as u64),
|
||||
Instr::Syscall,
|
||||
mov(ax, 0x3c),
|
||||
mov(di, 39),
|
||||
Instr::Syscall,
|
||||
],
|
||||
})]);
|
||||
program.entry = Some(entry);
|
||||
let linked = program.compile().expect("failed to compile");
|
||||
let binary = linked.to_elf();
|
||||
let path = "./x86_64_test";
|
||||
let mut file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.mode(0o750)
|
||||
.open(path)
|
||||
.expect("Failed to create file");
|
||||
file.write_all(&binary).expect("Failed to write to file");
|
||||
file.sync_all().expect("Failed to sync file");
|
||||
drop(file);
|
||||
println!("running...");
|
||||
let gdb = false;
|
||||
let mut proc = if gdb {
|
||||
let mut cmd = Command::new("gdb");
|
||||
#[rustfmt::skip]
|
||||
cmd.args([
|
||||
"-q",
|
||||
"-ex", "starti",
|
||||
"-ex", "layout asm",
|
||||
"-ex", "focus next",
|
||||
"x86_64_test",
|
||||
]);
|
||||
cmd
|
||||
} else {
|
||||
Command::new(path)
|
||||
}
|
||||
.spawn()
|
||||
.expect("failed to run");
|
||||
let status = proc.wait().expect("failed to wait");
|
||||
if let Some(code) = status.code() {
|
||||
std::process::exit(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod bin;
|
||||
#[cfg(test)]
|
||||
mod reg;
|
||||
#[cfg(test)]
|
||||
use super::*;
|
||||
@@ -0,0 +1,76 @@
|
||||
use super::*;
|
||||
|
||||
fn eq(expected: impl AsRef<[u8]>, asm: Instr) {
|
||||
let expected = expected.as_ref();
|
||||
let mut encoder = Encoder::new(0);
|
||||
if let Err(e) = encoder.asm(asm) {
|
||||
panic!("expected {expected:x?}, failed to compile: {}", e.msg);
|
||||
}
|
||||
let res = encoder.data;
|
||||
assert_eq!(expected, &res[..], "expected {expected:x?}, got {res:x?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reg_reg() {
|
||||
// used objdump on some nasm compiled assembly
|
||||
eq([0x48, 0x89, 0xd8], mov(rax, rbx));
|
||||
eq([0x89, 0xd8], mov(eax, ebx));
|
||||
eq([0x66, 0x89, 0xd8], mov(ax, bx));
|
||||
eq([0x88, 0xd8], mov(al, bl));
|
||||
eq([0x88, 0xfc], mov(ah, bh));
|
||||
|
||||
eq([0x88, 0xf8], mov(al, bh));
|
||||
eq([0x88, 0xdc], mov(ah, bl));
|
||||
eq([0x40, 0x88, 0xe7], mov(dil, spl));
|
||||
|
||||
eq([0x4d, 0x89, 0xc8], mov(r8, r9));
|
||||
eq([0x45, 0x89, 0xc8], mov(r8d, r9d));
|
||||
eq([0x66, 0x45, 0x89, 0xc8], mov(r8w, r9w));
|
||||
eq([0x45, 0x88, 0xc8], mov(r8b, r9b));
|
||||
|
||||
eq([0x49, 0x89, 0xc0], mov(r8, rax));
|
||||
eq([0x4c, 0x89, 0xc0], mov(rax, r8));
|
||||
eq([0x4d, 0x89, 0xd1], mov(r9, r10));
|
||||
|
||||
eq([0x4d, 0x89, 0xe0], mov(r8, r12));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reg_imm() {
|
||||
eq(
|
||||
[0x49, 0xbf, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r15, 0x123456789abcdef0),
|
||||
);
|
||||
eq(
|
||||
[0x49, 0xb8, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r8, 0x123456789abcdef0),
|
||||
);
|
||||
eq(
|
||||
[0x49, 0xb9, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r9, 0x123456789abcdef0),
|
||||
);
|
||||
eq([0x41, 0xb9, 0x78, 0x56, 0x34, 0x12], mov(r9d, 0x12345678));
|
||||
eq([0x66, 0x41, 0xb9, 0x34, 0x12], mov(r9w, 0x1234));
|
||||
eq([0x41, 0xb1, 0x12], mov(r9b, 0x12));
|
||||
eq([0x41, 0xb0, 0x12], mov(r8b, 0x12));
|
||||
eq([0x41, 0xb7, 0x12], mov(r15b, 0x12));
|
||||
|
||||
eq(
|
||||
[0x48, 0xb8, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rax, 0x123456789abcdef0),
|
||||
);
|
||||
eq(
|
||||
[0x48, 0xbb, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rbx, 0x123456789abcdef0),
|
||||
);
|
||||
eq(
|
||||
[0x48, 0xbf, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rdi, 0x123456789abcdef0),
|
||||
);
|
||||
eq([0xbb, 0x78, 0x56, 0x34, 0x12], mov(ebx, 0x12345678));
|
||||
eq([0x66, 0xbb, 0x34, 0x12], mov(bx, 0x1234));
|
||||
eq([0xb3, 0x12], mov(bl, 0x12));
|
||||
eq([0xb7, 0x12], mov(bh, 0x12));
|
||||
eq([0xb4, 0x12], mov(ah, 0x12));
|
||||
eq([0x40, 0xb7, 0x12], mov(dil, 0x12));
|
||||
}
|
||||
Reference in New Issue
Block a user