diff --git a/code/asm/hello_files.asm b/code/asm/hello_files.asm new file mode 100644 index 0000000..1a9caf1 --- /dev/null +++ b/code/asm/hello_files.asm @@ -0,0 +1,136 @@ +; Hello Files! + +BITS 64 ; Explicitly specify 64-bit mode +DEFAULT REL ; Use RIP-relative addressing by default + +;region DSL +%define marg + +%define rcounter_32 ecx + +%define r8_32 r8d + +%define raccumulator rax +%define rcounter rcx +%define rdata rdx +%define rstack_ptr rsp +%define rstack_base_ptr rbp + +%define reg9 r9 +;endregion + +;region debug +%define debug_trap 3 +;endregion + +;region Memory +%define kilo 1024 + +%define nullptr 0 + +%macro assert_not_null 1 + cmp %1, nullptr + jnz %%+.passed + int debug_trap +%%+.passed ; macro-unique-prefix (%%) + internal expansion .passed is the label name +%endmacro + +; Usage: def_Slice %1: +%macro def_Slice 1 + struc Slice_ %+ %1 + .ptr: resq 1 + .len: resq 1 + endstruc +%endmacro + +def_Slice Byte +def_Slice Str8 +;endregion Memory + +;region Str8 Table +; Usage: lit %1: , %2: +%macro lit 2 + lit_ %+ %1: db %2 + lit_ %+ %1 %+ _len: equ $ - (lit_ %+ %1) +%endmacro + +; Usage: stack_slice %1: , %2 +%macro stack_slice %2 + +%endmacro + +section .lits progbits noexec nowrite + lit path_hello_files_asm, `./code/asm/hello_files.asm` +;endregion Str8 Table + +;region WinAPI +; kernel32.lib +; Console IO +extern GetStdHandle +extern WriteConsoleA +; File API +extern CreateFileA +extern GetFileSizeEx +extern GetLastError +extern ReadFile + +%define MS_STD_OUTPUT_HANDLE 11 + +%define wapi_shadow_width 48 +%macro wapi_shadow_space 0 + push rstack_base_ptr + mov rstack_base_ptr, rstack_ptr + sub rstack_ptr, wapi_shadow_width +%endmacro +%define wapi_arg4_offset 28 +%define wapi_arg5_offset 32 + +%define wapi_write_console_written_chars reg9 +%macro wapi_write_console 2 + mov rcounter,[%1] ; Console Handle + lea rdata, [%2] ; Slice_Str8.Ptr + mov r8_32, %2 %+ _len ; Slice_Str8.Len + lea reg9, [rstack_ptr + wapi_arg4_offset] ; Written chars + mov qword [rstack_ptr + wapi_arg5_offset], 0 ; Reserved (must be 0) + call WriteConsoleA +%endmacro + +section .data + std_out_hndl dq 0 +;endregion + +api_file_read_contents: + section .text + %define result ;TODO(Ed): figure out the convention + %define path ;TODO(Ed): figure out the convention + %define backing ;TODO(Ed): figure out the convention + + assert_not_null result + slice_assert path + slice_assert backing + ; local_persist scratch_kilo: [64 * kilo]U8; (api_file_read_contents.scratch_kilo) + + %define slice_fmem_scratch ;TODO(Ed): figure this out + call str8_to_cstr_capped path_c_str, path, slice_fmem_scratch + + ; TODO(Ed): Form-fill + call CreateFileA + + leave + ret + + section .bss + api_file_read_contents.scratch_kilo: resb 64 * kilo + api_file_read_contents.path_cstr: resq 1 + +section .text +global main + +main: + wapi_shadow_space + + ; TODO(Ed): Form-fill + call api_file_read_contents + + leave + ret diff --git a/scripts/build_hello_files.ps1 b/scripts/build_hello_files.ps1 new file mode 100644 index 0000000..c911ea8 --- /dev/null +++ b/scripts/build_hello_files.ps1 @@ -0,0 +1,76 @@ +$ps1_devshell = join-path $PSScriptRoot 'helpers/devshell.ps1' +. $ps1_devshell -arch amd64 +$path_root = split-path -Path $PSScriptRoot -Parent +$path_build = join-path $path_root 'build' +$path_code = join-path $path_root 'code' +$path_asm = join-path $path_code 'asm' +$path_toolchain = join-path $path_root 'toolchain' +$path_radlink = join-path $path_toolchain 'radlink' + +if ((test-path $path_build) -eq $false) { + new-item -itemtype directory -path $path_build +} + +$hello_nasm = join-path $path_asm 'hello_files.asm' +$listing = join-path $path_build 'hello_files.list' +$link_obj = join-path $path_build 'hello_files.o' +$exe = join-path $path_build 'hello_files.exe' + +$nasm = 'nasm' +$radlink = join-path $path_radlink 'radlink.exe' + +push-location $path_root +$f_assemble_only = '-a' +$f_bin_fmt_coff = '-f coff' +$f_bin_fmt_win64 = '-f win64' +$f_debug = '-g' +$f_debug_fmt_win64 = '-g cv8' +$f_dmacro = '-Dmacro=' +$f_Ipath = '-Ipath ' +$f_listing = '-l' +$f_preprocess_only = '-E' +$f_optimize_none = '-O0' +$f_optimize_min = '-O1' +$f_optimize_multi = '-Ox' +$f_optimize_multi_disp = '-Ov' +$f_outfile = '-o ' +$f_warnings_as_errors = '-Werror' +$args = @( + $hello_nasm, + $f_optimize_none, + # $f_preprocess_only, + $f_bin_fmt_win64, + $f_debug_fmt_win64, + ($f_listing + $listing), + ($f_outfile + $link_obj) +) +& $nasm $args + +$lib_kernel32 = 'kernel32.lib' +$lib_msvcrt = 'msvcrt.lib' + +$link = 'link.exe' + +$link_debug = '/DEBUG:' +$link_entrypoint = '/ENTRY:' +$link_library = '/' +$link_outfile = '/OUT:' +$link_win_machine_64 = '/MACHINE:X64' +$link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' +$link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' +$rad_debug = '/RAD_DEBUG' +$rad_debug_name = '/RAD_DEBUG_NAME:' +$rad_large_pages = '/RAD_LARGE_PAGES:' +$args = @( + $rad_debug, + # ($link_debug + 'FULL'), + $link_win_machine_64, + $link_win_subsystem_console, + $lib_kernel32, + # $lib_msvcrt, + ($link_entrypoint + 'main'), + ($link_outfile + $exe), + $link_obj +) +& $radlink $args +pop-location