WINDOWS HELLO WORLD (scuffed)

This commit is contained in:
2026-06-09 01:02:40 -04:00
parent e4acaf40aa
commit ea305909a0
6 changed files with 58 additions and 8 deletions
+14
View File
@@ -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 {
+13
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq)]
pub struct Reg(u8);
#[derive(Clone, Copy)]
+24 -1
View File
@@ -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);
+6 -6
View File
@@ -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));
BIN
View File
Binary file not shown.