honestly just fuck windows

This commit is contained in:
MCorange 2023-03-29 16:13:51 +03:00
parent d54677ca5e
commit e7a37a1f53
8 changed files with 115 additions and 25 deletions

5
kernel32.def Normal file
View File

@ -0,0 +1,5 @@
LIBRARY KERNEL32.DLL
EXPORTS
WriteConsoleA
GetStdHandle
ExitProcess

BIN
libkernel32.a Normal file

Binary file not shown.

View File

@ -4,7 +4,7 @@ use color_eyre::Result;
use crate::compile::Folders;
use crate::info;
pub fn linux_x86_64_compile_and_link(folders: &Folders, quiet: bool) -> Result<()> {
pub fn cmpile_and_link(folders: &Folders, quiet: bool) -> Result<()> {
let nasm_args = [
"-fwin32",
@ -17,14 +17,12 @@ pub fn linux_x86_64_compile_and_link(folders: &Folders, quiet: bool) -> Result<(
folders.of_o.to_str().unwrap(),
"-o",
folders.of_c.to_str().unwrap(),
"-L",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Lib",
"-l",
"kernel32"
"-nostdlib", "-nostartfiles",
"-lC:\\Users\\gvida\\@Projects\\rust\\mclang2\\libkernel32.a",
];
let mut proc = if cfg!(target_os = "windows") {
let mut proc = if !cfg!(target_os = "windows") {
return Ok(());
} else {
Command::new("nasm")
@ -43,21 +41,21 @@ pub fn linux_x86_64_compile_and_link(folders: &Folders, quiet: bool) -> Result<(
}
let mut proc2 = if cfg!(target_os = "windows") {
let mut proc2 = if !cfg!(target_os = "windows") {
return Ok(());
} else {
Command::new("ld")
Command::new("gcc")
.args(ld_args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()?
};
if !quiet {
info!("running 'ld {}'", ld_args.join(" "));
info!("running 'gcc {}'", ld_args.join(" "));
}
let exit2 = proc2.wait()?;
if !quiet {
info!("ld process exited with code {}", exit2);
info!("gcc process exited with code {}", exit2);
}
@ -65,13 +63,13 @@ pub fn linux_x86_64_compile_and_link(folders: &Folders, quiet: bool) -> Result<(
Ok(())
}
pub fn linux_x86_64_run(bin: &Path, args: &[String], quiet: bool) -> Result<i32> {
pub fn run(bin: &Path, args: &[String], quiet: bool) -> Result<i32> {
let bin = PathBuf::from(
format!("./{}", bin.to_string_lossy())
);
let mut proc = if cfg!(target_os = "windows") {
let mut proc = if !cfg!(target_os = "windows") {
return Ok(0);
} else {
Command::new(bin.clone())

View File

@ -2,8 +2,8 @@ mod commands;
use std::{fs, io::{Write, BufWriter}};
use crate::{constants::{Operator, OpType, KeywordType}, Args};
use color_eyre::Result;
use commands::linux_x86_64_compile_and_link;
use commands::linux_x86_64_run;
use commands::cmpile_and_link;
use commands::run;
use crate::constants::InstructionType;
use super::Folders;
@ -18,6 +18,10 @@ pub fn compile(tokens: &[Operator], args: &Args, folders: &Folders) -> Result<i3
writeln!(writer, "BITS 64")?;
writeln!(writer, "segment .text")?;
writeln!(writer, "extern WriteConsoleA")?;
writeln!(writer, "extern GetStdHandle")?;
writeln!(writer, "extern ExitProcess")?;
writeln!(writer, "print:")?;
writeln!(writer, " mov r9, -3689348814741910323")?;
writeln!(writer, " sub rsp, 40")?;
@ -47,13 +51,28 @@ pub fn compile(tokens: &[Operator], args: &Args, folders: &Folders) -> Result<i3
writeln!(writer, " xor eax, eax")?;
writeln!(writer, " lea rsi, [rsp+32+rdx]")?;
writeln!(writer, " mov rdx, r8")?;
writeln!(writer, " mov rax, 1")?;
writeln!(writer, " syscall")?;
writeln!(writer, " add rsp, 40")?;
// 8 bytes of temporary storage for `bytes`.
// allocate 32 bytes of stack for shadow space.
// 8 bytes for the 5th parameter of WriteConsole.
// An additional 8 bytes for padding to make RSP 16 byte aligned.
writeln!(writer, " sub rsp, 8+8+32")?;
// get std handle
writeln!(writer, " mov ecx, -11")?;
writeln!(writer, " call GetStdHandle")?;
writeln!(writer, " mov rcx, rax")?; // handle
writeln!(writer, " mov r8, rdx")?; // text len
writeln!(writer, " mov rdx, rsi")?; // text
writeln!(writer, " lea r9, [rsp-16]")?; // Address for `bytes`
// RSP-17 through RSP-48 are the 32 bytes of shadow space
writeln!(writer, " mov qword [rsp-56], 0")?; // First stack parameter of WriteConsoleA function
writeln!(writer, " add rsp, 8+8+32+40")?;
writeln!(writer, " call WriteConsoleA")?;
writeln!(writer, " ret")?;
writeln!(writer, "global _start")?;
writeln!(writer, "_start:")?;
writeln!(writer, "sub rsp, 8")?; //At _start the stack is 8 bytes misaligned because there is a return address to the MSVCRT runtime library on the stack.
let mut ti = 0;
while ti < tokens.len() {
@ -395,9 +414,8 @@ pub fn compile(tokens: &[Operator], args: &Args, folders: &Folders) -> Result<i3
}
}
writeln!(writer, "addr_{ti}:")?;
writeln!(writer, " mov rax, 60")?;
writeln!(writer, " mov rdi, 0")?;
writeln!(writer, " syscall")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " call ExitProcess")?;
writeln!(writer, "segment .data")?;
for (_, s) in strings.iter().enumerate() {
let s_chars = s.chars().map(|c| (c as u32).to_string()).collect::<Vec<String>>();
@ -409,9 +427,9 @@ pub fn compile(tokens: &[Operator], args: &Args, folders: &Folders) -> Result<i3
writeln!(writer, "mem: resb {}", crate::compile::MEM_SZ)?;
writer.flush()?;
linux_x86_64_compile_and_link(folders, args.quiet)?;
cmpile_and_link(folders, args.quiet)?;
if args.run {
let c = linux_x86_64_run(&folders.of_c, &[], args.quiet)?;
let c = run(&folders.of_c, &[], args.quiet)?;
return Ok(c);
}

View File

@ -191,9 +191,16 @@ impl TokenType {
}
pub type Loc = (String, usize, usize);
pub mod targets {
pub const LINUX_X86_64: &'static str = "linux_x86_64";
pub const WIN32_X86_64: &'static str = "win32_x86_64";
}
pub fn get_win32_syscall(n: usize) {
match n {
_ => panic!("Unknown syscall {n}")
}
}

View File

@ -1,3 +1,3 @@
#ifdef __win32__
69
10 print
#endif

62
test.nasm Normal file
View File

@ -0,0 +1,62 @@
BITS 64
segment .text
extern WriteConsoleA
extern GetStdHandle
extern ExitProcess
print:
mov r9, -3689348814741910323
sub rsp, 40
mov BYTE [rsp+31], 10
lea rcx, [rsp+30]
.L2:
mov rax, rdi
lea r8, [rsp+32]
mul r9
mov rax, rdi
sub r8, rcx
shr rdx, 3
lea rsi, [rdx+rdx*4]
add rsi, rsi
sub rax, rsi
add eax, 48
mov BYTE [rcx], al
mov rax, rdi
mov rdi, rdx
mov rdx, rcx
sub rcx, 1
cmp rax, 9
ja .L2
lea rax, [rsp+32]
mov edi, 1
sub rdx, rax
xor eax, eax
lea rsi, [rsp+32+rdx]
mov rdx, r8
sub rsp, 8+8+32
mov ecx, -11
call GetStdHandle
mov rcx, rax
mov r8, rdx
mov rdx, rsi
lea r9, [rsp-16]
mov qword [rsp-56], 0
add rsp, 8+8+32+40
call WriteConsoleA
ret
global _start
_start:
sub rsp, 8
addr_0:
;; -- push int 10
mov rax, 10
push rax
addr_1:
;; -- print
pop rdi
call print
addr_2:
mov rcx, 0
call ExitProcess
segment .data
segment .bss
mem: resb 640000

BIN
test.o Normal file

Binary file not shown.