WINDOWS HELLO WORLD (scuffed)
This commit is contained in:
@@ -10,6 +10,8 @@ pub struct Asm {
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Instr {
|
||||
Mov { dst: RegMode, src: RegImmMem },
|
||||
// TODO: horrible
|
||||
MemMov { reg: RegMode, offset: u64, val: u64 },
|
||||
Int(u8),
|
||||
Call(Symbol),
|
||||
CallMem(Symbol),
|
||||
@@ -45,6 +47,18 @@ impl From<u64> for RegImmMem {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for RegImmMem {
|
||||
fn from(value: i64) -> Self {
|
||||
Self::Imm(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for RegImmMem {
|
||||
fn from(value: i32) -> Self {
|
||||
Self::Imm(value as u32 as u64)
|
||||
}
|
||||
}
|
||||
|
||||
mod fns {
|
||||
use super::*;
|
||||
pub fn mov(dst: RegMode, src: impl Into<RegImmMem>) -> Instr {
|
||||
|
||||
@@ -110,6 +110,18 @@ impl Encoder<'_> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mem_mov(&mut self, reg: RegMode, offset: u64, val: u64) {
|
||||
assert!(offset <= u8::MAX as u64);
|
||||
assert!(val <= u32::MAX as u64);
|
||||
self.data
|
||||
.extend([0x48 | ((reg.gt8() as u8) << 2), 0xc7, 0x40 | reg.base()]);
|
||||
if reg.reg == rsp.reg {
|
||||
self.data.push(0x24)
|
||||
}
|
||||
self.data.push(offset as u8);
|
||||
self.data.extend((val as u32).to_le_bytes());
|
||||
}
|
||||
|
||||
pub fn lea(&mut self, dst: RegMode, sym: Symbol) {
|
||||
self.data.extend([
|
||||
0x48 | ((dst.gt8() as u8) << 2),
|
||||
@@ -184,6 +196,7 @@ impl Encoder<'_> {
|
||||
pub fn asm(&mut self, instr: Instr) -> Result<(), CompilerMsg> {
|
||||
match instr {
|
||||
Instr::Mov { dst, src } => self.mov(dst, src)?,
|
||||
Instr::MemMov { reg, offset, val } => self.mem_mov(reg, offset, val),
|
||||
Instr::Int(code) => self.int(code),
|
||||
Instr::Syscall => self.syscall(),
|
||||
Instr::Lea { dst, sym } => self.lea(dst, sym),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct Reg(u8);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
||||
@@ -79,10 +79,33 @@ fn windows() {
|
||||
let mut program = Program::<X86_64>::default();
|
||||
let [get_std_handle, write_file, exit_process] =
|
||||
program.external("KERNEL32.dll", ["GetStdHandle", "WriteFile", "ExitProcess"]);
|
||||
let text = b"Hello world!\n";
|
||||
let text_sym = program.ro_data("hello_en", text);
|
||||
let written = program.ro_data("written", [0; 4]);
|
||||
let entry = program.func(
|
||||
"main",
|
||||
[BInstr::Asm(Asm {
|
||||
instrs: vec![Instr::Sub, mov(ecx, 40), Instr::CallMem(exit_process)],
|
||||
instrs: vec![
|
||||
Instr::Sub,
|
||||
// stdout
|
||||
mov(ecx, -11),
|
||||
Instr::CallMem(get_std_handle),
|
||||
// write
|
||||
mov(rcx, rax),
|
||||
lea(rdx, text_sym),
|
||||
mov(r8d, text.len() as u64),
|
||||
lea(r9, written),
|
||||
Instr::MemMov {
|
||||
reg: rsp,
|
||||
offset: 0x20,
|
||||
val: 0,
|
||||
},
|
||||
// mov qword [rsp+32], 0
|
||||
Instr::CallMem(write_file),
|
||||
// exit
|
||||
mov(ecx, 39),
|
||||
Instr::CallMem(exit_process),
|
||||
],
|
||||
})],
|
||||
);
|
||||
program.entry = Some(entry);
|
||||
|
||||
@@ -40,15 +40,15 @@ fn reg_reg() {
|
||||
fn reg_imm() {
|
||||
eq(
|
||||
[0x49, 0xbf, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r15, 0x123456789abcdef0),
|
||||
mov(r15, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq(
|
||||
[0x49, 0xb8, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r8, 0x123456789abcdef0),
|
||||
mov(r8, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq(
|
||||
[0x49, 0xb9, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(r9, 0x123456789abcdef0),
|
||||
mov(r9, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq([0x41, 0xb9, 0x78, 0x56, 0x34, 0x12], mov(r9d, 0x12345678));
|
||||
eq([0x66, 0x41, 0xb9, 0x34, 0x12], mov(r9w, 0x1234));
|
||||
@@ -58,15 +58,15 @@ fn reg_imm() {
|
||||
|
||||
eq(
|
||||
[0x48, 0xb8, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rax, 0x123456789abcdef0),
|
||||
mov(rax, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq(
|
||||
[0x48, 0xbb, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rbx, 0x123456789abcdef0),
|
||||
mov(rbx, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq(
|
||||
[0x48, 0xbf, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12],
|
||||
mov(rdi, 0x123456789abcdef0),
|
||||
mov(rdi, 0x123456789abcdef0u64),
|
||||
);
|
||||
eq([0xbb, 0x78, 0x56, 0x34, 0x12], mov(ebx, 0x12345678));
|
||||
eq([0x66, 0xbb, 0x34, 0x12], mov(bx, 0x1234));
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user