honestly just fuck windows
This commit is contained in:
parent
d54677ca5e
commit
e7a37a1f53
5
kernel32.def
Normal file
5
kernel32.def
Normal file
|
@ -0,0 +1,5 @@
|
|||
LIBRARY KERNEL32.DLL
|
||||
EXPORTS
|
||||
WriteConsoleA
|
||||
GetStdHandle
|
||||
ExitProcess
|
BIN
libkernel32.a
Normal file
BIN
libkernel32.a
Normal file
Binary file not shown.
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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}")
|
||||
}
|
||||
|
||||
|
||||
}
|
62
test.nasm
Normal file
62
test.nasm
Normal 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
|
Loading…
Reference in New Issue
Block a user