diff --git a/code/asm/asm.user b/code/asm/asm.user new file mode 100644 index 0000000..c60ecbe --- /dev/null +++ b/code/asm/asm.user @@ -0,0 +1,178 @@ +// raddbg 0.9.18 user file + +window: +{ + size: 1536.000000 864.000000 + panels: + { + 0.25: + { + 0.25: + { + watch: + { + expression: "" + selected + } + watch: expression: "query:types" + } + 0.25: + { + watch: + { + expression: "query:threads" + selected + } + watch: expression: "query:targets" + watch: expression: "query:breakpoints" + watch: expression: "query:watch_pins" + } + 0.25: + { + disasm: + { + expression: "" + selected + } + text: expression: "query:output" + } + 0.25: + { + watch: + { + expression: "query:call_stack" + selected + } + watch: expression: "query:modules" + } + } + 0.75: + { + getting_started: selected + selected + } + } + split_x + pos: 26 26 + monitor: "\\\\.\\DISPLAY1" +} +keybindings: +{ + { kill_all f5 shift } + { step_into_inst f11 alt } + { step_over_inst f10 alt } + { step_out f11 shift } + { halt x ctrl shift } + { halt pause } + { run f5 } + { restart f5 ctrl shift } + { step_into f11 } + { step_over f10 } + { run_to_line f10 ctrl } + { set_next_statement f10 ctrl shift } + { inc_window_font_size equal alt } + { dec_window_font_size minus alt } + { window n ctrl shift } + { toggle_fullscreen return ctrl } + { new_panel_right p ctrl } + { new_panel_down minus ctrl } + { rotate_panel_columns 2 ctrl } + { next_panel comma ctrl } + { prev_panel comma ctrl shift } + { focus_panel_right right ctrl alt } + { focus_panel_left left ctrl alt } + { focus_panel_up up ctrl alt } + { focus_panel_down down ctrl alt } + { undo z ctrl } + { redo y ctrl } + { go_back left alt } + { go_forward right alt } + { close_panel p ctrl shift alt } + { next_tab page_down ctrl } + { prev_tab page_up ctrl } + { next_tab tab ctrl } + { prev_tab tab ctrl shift } + { move_tab_right page_down ctrl shift } + { move_tab_left page_up ctrl shift } + { close_tab w ctrl } + { tab_bar_top up ctrl shift alt } + { tab_bar_bottom down ctrl shift alt } + { open_tab t ctrl } + { open o ctrl } + { switch i ctrl } + { switch_to_partner_file o alt } + { open_user n ctrl shift alt } + { open_project n ctrl alt } + { open_user o ctrl shift alt } + { open_project o ctrl alt } + { save_user s ctrl shift alt } + { save_project s ctrl shift } + { edit f2 } + { accept return } + { accept space } + { cancel esc } + { move_left left } + { move_right right } + { move_up up } + { move_down down } + { move_left_select left shift } + { move_right_select right shift } + { move_up_select up shift } + { move_down_select down shift } + { move_left_chunk left ctrl } + { move_right_chunk right ctrl } + { move_up_chunk up ctrl } + { move_down_chunk down ctrl } + { move_up_page page_up } + { move_down_page page_down } + { move_up_whole home ctrl } + { move_down_whole end ctrl } + { move_left_chunk_select left ctrl shift } + { move_right_chunk_select right ctrl shift } + { move_up_chunk_select up ctrl shift } + { move_down_chunk_select down ctrl shift } + { move_up_page_select page_up shift } + { move_down_page_select page_down shift } + { move_up_whole_select home ctrl shift } + { move_down_whole_select end ctrl shift } + { move_up_reorder up alt } + { move_down_reorder down alt } + { move_home home } + { move_end end } + { move_home_select home shift } + { move_end_select end shift } + { select_all a ctrl } + { delete_single delete } + { delete_chunk delete ctrl } + { backspace_single backspace } + { backspace_chunk backspace ctrl } + { copy c ctrl } + { copy insert ctrl } + { cut x ctrl } + { paste v ctrl } + { paste insert shift } + { insert_text null } + { move_next tab } + { move_prev tab shift } + { goto_line g ctrl } + { goto_address g alt } + { search f ctrl } + { search_backwards r ctrl } + { find_next f3 } + { find_prev f3 ctrl } + { find_selected_thread f4 } + { goto_name j ctrl } + { goto_name_at_cursor f12 } + { toggle_watch_expr_at_cursor w alt } + { toggle_watch_expr_at_mouse d ctrl } + { toggle_watch_pin f9 ctrl } + { toggle_breakpoint f9 } + { add_address_breakpoint f9 shift } + { add_function_breakpoint f9 ctrl shift } + { attach f6 shift } + { open_palette f1 } + { open_palette p ctrl shift } + { log_marker m ctrl shift alt } + { toggle_dev_menu d ctrl shift alt } +} +current_path: "C:/users/ed/appdata/roaming/raddbg" diff --git a/code/asm/hello_files.asm b/code/asm/hello_files.asm index ddff3e7..01ed3ff 100644 --- a/code/asm/hello_files.asm +++ b/code/asm/hello_files.asm @@ -197,7 +197,7 @@ DEFAULT REL ; Use RIP-relative addressing by default %define kilo 1024 ; Usage: def_array -%macro def_farray 2 +%macro def_farray 2+ struc %1 .ptr: resb %2 endstruc @@ -269,6 +269,45 @@ def_Slice Byte %endif %endmacro +; Usage: cf (call-frame begin) +; Establishes a new stack frame, saving the caller's frame. +; This is a standard function prologue. +%macro cf 0 + push rstack_base_ptr ; Save the caller's frame pointer (RBP) + mov rstack_base_ptr, rstack_ptr ; Set our new frame pointer to the current stack position +%endmacro + +; Usage: cf_alloc (call-frame allocate) +; Immediately allocates a block of memory on the stack. +%macro cf_alloc 1 + sub rstack_ptr, %1 ; Allocate space by subtracting from the stack pointer (RSP) +%endmacro + +; Usage: cf_commit (call-frame commit) +; Finalizes the stack frame by ensuring it is correctly aligned for a function call. +%macro cf_commit 0 + ; The Windows x64 ABI requires the stack pointer (RSP) to be 16-byte + ; aligned immediately before a CALL instruction. This command ensures alignment + ; by clearing the last 4 bits of RSP, rounding it down to the nearest multiple of 16. + and rstack_ptr, ~15 +%endmacro + +; Usage: cf_end (call-frame end) +; Tears down the stack frame, deallocating all memory and restoring the caller's frame. +; This is a standard function epilogue. +%macro cf_end 0 + ; Deallocate the entire frame at once by resetting RSP to the saved RBP + mov rstack_ptr, rstack_base_ptr + ; Restore the caller's frame pointer + pop rstack_base_ptr +%endmacro + +%macro cf_ctbl 1 + cf + cf_alloc %1 %+ _ctbl_size + cf_commit +%endmacro + ; Usage stac_alloc %1: %macro stack_push 1 push rstack_base_ptr @@ -280,39 +319,6 @@ def_Slice Byte pop rstack_base_ptr %endmacro -; We will still use R11 as a temporary accumulator. - -; Usage: begin_call_prep -; Initializes the accumulator and reserves 8 bytes in the frame -; to store the total frame size itself. -%macro call_frame 0 - xor r11, r11 ; Clear the accumulator register to 0 - add r11, 8 ; Reserve 8 bytes for the size storage -%endmacro - -; Usage: stack_alloc -%macro call_frame_alloc 1 - add r11, %1 -%endmacro - -; Usage: commit_call_frame -%macro call_frame_commit 0 - add r11, 15 - and r11, ~15 - ; Aligned the total size up to the nearest 16 bytes - - sub rsp, r11 ; Allocate the final, aligned block on the stack - mov [rsp], r11 ; Store the total size at the bottom of the frame we just created -%endmacro - -; Usage: end_call -; Retrieves the size from the stack and deallocates the frame. -; This macro no longer depends on R11. -%macro call_frame_end 0 - mov r11, [rsp] ; Retrieve the total size from the bottom of our frame - add rsp, r11 ; Deallocate the entire frame -%endmacro - ;endregion Memory ;region Math @@ -366,6 +372,7 @@ str8_to_cstr_capped: push raccumulator push rdst_id push rsrc_id + sub rstack_ptr, 8 ; U64 raccumulator = min(content.len, mem.len - 1); mov rsrc_id, qword [mem + Slice_Byte.len] sub rsrc_id, 1 @@ -380,6 +387,7 @@ str8_to_cstr_capped: mov byte [rdst_id + raccumulator], 0 ; return cast(char*, mem.ptr); mov result, qword [mem + Str8.ptr] + add rstack_ptr, 8 pop rsrc_id pop rdst_id pop raccumulator @@ -447,7 +455,6 @@ struc CreateFileA_ctbl .dwCreationDisposition: resq 1 .dwFlagsAndAttributes: resq 1 .hTemplateFile: resq 1 - ._pad resq 1 endstruc ; rcx: hFile @@ -523,7 +530,6 @@ file_read_contents: push r12 ; result push r13 ; backing push r14 ; file_size - sub rsp, 8 mov r12, result mov r13, backing %define result r12 @@ -535,16 +541,16 @@ file_read_contents: ; path_cstr = rcounter; path_len has will be discarded in the CreateFileA call %define path_cstr rcounter - stack_push CreateFileA_ctbl_size ; call-frame CreateFileA { + cf_ctbl CreateFileA ; call-frame CreateFileA { ; rcounter = path_cstr mov rdata_32, MS_GENERIC_READ ; dwDesiredAccess = MS_GENERIC_READ mov r8_32, MS_FILE_SHARE_READ ; dwShareMode = MS_FILE_SHARE_READ xor r9, r9 ; lpSecurityAttributes = nullptr - mov dword [rstack_ptr + CreateFileA_ctbl.dwCreationDisposition], MS_OPEN_EXISTING ; stack.ptr[.dwCreationDisposition] = MS_OPEN_EXISTING - mov dword [rstack_ptr + CreateFileA_ctbl.dwFlagsAndAttributes ], MS_FILE_ATTRIBUTE_NORMAL ; stack.ptr[.dwFlagsAndAttributes ] = MS_FILE_ATTRIBUTE_NORMAL + mov qword [rstack_ptr + CreateFileA_ctbl.dwCreationDisposition], MS_OPEN_EXISTING ; stack.ptr[.dwCreationDisposition] = MS_OPEN_EXISTING + mov qword [rstack_ptr + CreateFileA_ctbl.dwFlagsAndAttributes ], MS_FILE_ATTRIBUTE_NORMAL ; stack.ptr[.dwFlagsAndAttributes ] = MS_FILE_ATTRIBUTE_NORMAL mov qword [rstack_ptr + CreateFileA_ctbl.hTemplateFile ], nullptr ; stack.ptr[.hTemplateFile ] = nullptr - call CreateFileA ; CreateFileA <- rcounter, rdata, r8, r9, stack - stack_pop ; } + call CreateFileA ; CreateFileA <- rcounter, rdata, r8, r9, stack + cf_end ; } ; B32 open_failed = raccumulator == MS_INVALID_HANDLE_VALUE ; if (open_failed) goto %%.error_exit @@ -554,11 +560,11 @@ file_read_contents: mov rbase, raccumulator ; rbase = id_file %define id_file rbase - stack_push GetFileSizeEx_ctbl_size ; call-frame GetFileSizeEx { + cf_ctbl GetFileSizeEx ; call-frame GetFileSizeEx { mov rcounter, id_file ; rcounter = id_file lea rdata, [result + FileOpInfo.content + Slice_Byte.len] ; lpFileSize = result.content.len - call GetFileSizeEx ; GetFileSizeEx <- rcounter, rdata, stack - stack_pop ; } + call GetFileSizeEx ; GetFileSizeEx <- rcounter, rdata, stack + cf_end ; } ; B32 not_enough_backing = result.content.len > backing.len ; if (not_enough_backing) goto .error_close_handle @@ -575,14 +581,14 @@ file_read_contents: %define file_size r14d mov r14d, r9d - stack_push ReadFile_ctbl_size ; call-frame ReadFile { + cf_ctbl ReadFile ; call-frame ReadFile { mov rcounter, id_file ; hfile: rcounter = rbase mov rdata, [backing + Slice_Byte.ptr ] ; lpBuffer: rdata = backing.ptr mov r8_32, file_size ; nNumberOfBytesToRead: r8_32 = file_size lea r9, [result + FileOpInfo.content + Slice_Byte.len] ; lpNumberOfBytesRead: r9 = & result.content.len mov qword [rstack_ptr + ReadFile_ctbl.lpOverlapped], 0 ; lpOverlapped: nullptr - call ReadFile ; ReadFile <- rcounter, rata, r8, r9, stack - stack_pop ; } + call ReadFile ; ReadFile <- rcounter, rata, r8, r9, stack + cf_end ; } ; B32 read_failed = ! read_result ; if (read_failed) goto .error_exit @@ -595,10 +601,10 @@ file_read_contents: jne .error_close_handle ; CloseHandle(id_file) - stack_push CloseHandle_ctbl_size ; call-frame CloseHandle { - mov rcounter, id_file ; rcounter = id_file (rbase) - call CloseHandle ; CloseHandle <- rcounter, stack - stack_pop ; } + cf_ctbl CloseHandle ; call-frame CloseHandle { + mov rcounter, id_file ; rcounter = id_file (rbase) + call CloseHandle ; CloseHandle <- rcounter, stack + cf_end ; } ; reslt.content.ptr = raccumulator mov raccumulator, [backing + Slice_Byte.ptr] ; raccumulator = backing.ptr @@ -606,10 +612,10 @@ file_read_contents: jmp .cleanup ; goto .cleanup .error_close_handle: - stack_push CloseHandle_ctbl_size ; call-frame CloseHandle { - mov rcounter, rbase ; rcounter = id_file (rbase) - call CloseHandle ; CloseHandle <- rcounter, stack - stack_pop ; } + cf_ctbl CloseHandle ; call-frame CloseHandle { + mov rcounter, rbase ; rcounter = id_file (rbase) + call CloseHandle ; CloseHandle <- rcounter, stack + cf_end ; } .error_exit: ; result = {} @@ -617,7 +623,6 @@ file_read_contents: mov qword [result + FileOpInfo.content + Slice_Byte.len], 0 .cleanup: - add rsp, 8 pop r14 ; file_size pop backing pop result @@ -643,17 +648,19 @@ section .text global main %push proc_scope main: - stack_push GetStdHandle_ctbl_size ; call-frame GetStdHandle { - mov rcounter_32, MS_STD_OUTPUT_HANDLE ; rcounter.32 = MS_STD_OUTPUT_HANDLE - call GetStdHandle ; GetStdHandle <- rcounter, stack - mov [std_out_hndl], raccumulator ; std_out_hndl = raccumulator - stack_pop ; } + xor rcx, rcx + + cf_ctbl GetStdHandle ; call-frame GetStdHandle { + mov rcounter_32, MS_STD_OUTPUT_HANDLE ; rcounter.32 = MS_STD_OUTPUT_HANDLE + call GetStdHandle ; GetStdHandle <- rcounter, stack + cf_end ; } + + mov [std_out_hndl], raccumulator ; std_out_hndl = raccumulator - ; dbg_wipe_gprs %push calling - call_frame - call_frame_alloc Slice_Byte_size ; stack local_backing : Slice_byte - call_frame_commit ; call-frame file_read_contents { + cf ; call-frame file_read_contents { + cf_alloc Slice_Byte_size ; stack local_backing : Slice_byte + cf_commit %define local_backing rsp + Slice_Byte_size mov qword [local_backing + Slice_Byte.ptr], read_mem ; local_backing.ptr = read_mem.ptr mov qword [local_backing + Slice_Byte.len], Mem_128k_size ; local_backing.len = Mem_128k_size @@ -661,24 +668,25 @@ global main mov rdata, [path_hello_files_asm + Str8.ptr] ; rdata = path_hello_files.ptr mov r8, [path_hello_files_asm + Str8.len] ; r8 = path_hello_files.len lea r9, [local_backing] ; r9 = & local_backing - call file_read_contents ; read_file_contents <- rcounter, rdata, r8, r9, stack - call_frame_end ; } + call file_read_contents ; read_file_contents <- rcounter, rdata, r8, r9, stack + cf_end ; } %pop calling - stack_push WriteConsoleA_ctbl_size ; call-frame WriteConsoleA { + cf_ctbl WriteConsoleA ; call-frame WriteConsoleA { mov rcounter, [std_out_hndl] ; rcounter = std_out_hndl mov rdata, [file + FileOpInfo.content + Slice_Byte.ptr] ; rdata = file.content.ptr mov r8_32, [file + FileOpInfo.content + Slice_Byte.len] ; r8 = file.content.len lea r9, [rstack_ptr + WriteConsoleA_ctbl.lpNumberOfCharsWritten] ; r9 = & stack.ptr[WriteFileA.ctbl.lpNumberOfCharsWritten] mov qword [rstack_ptr + WriteConsoleA_ctbl.lpReserved], nullptr ; stack.ptr[.ctbl.lpRserved] = nullptr - call WriteConsoleA ; WriteConsoleA <- rcounter, rdata, r9, stack - stack_pop ; } + call WriteConsoleA ; WriteConsoleA <- rcounter, rdata, r9, stack + cf_end ; Exit program - stack_push ExitProcess_ctbl_size ; call-frame ExitProcess { - xor ecx, ecx ; ecx = 0 - call ExitProcess ; ExitProcess <- rcx, stack - ret ; } // Technically doesn't occur but here for "correctness" + cf_ctbl ExitProcess ; call-frame ExitProcess { + xor ecx, ecx ; ecx = 0 + call ExitProcess ; ExitProcess <- rcx, stack + cf_end ; } + ret %pop proc_scope section .bss diff --git a/code/asm/hello_files.proj b/code/asm/hello_files.proj index f749803..4fba62e 100644 --- a/code/asm/hello_files.proj +++ b/code/asm/hello_files.proj @@ -1,96 +1,12 @@ // raddbg 0.9.18 project file recent_file: path: "hello_files.asm" -recent_file: path: "../../build/hello_files.unit.asm" -recent_file: path: "../../asm_dip/code/asm/hello_files.asm" recent_file: path: "../../../code/asm/hello_files.asm" -recent_file: path: "../../../WATL_Exercise/c/watl.v0.msvc.c" -recent_file: path: "asm/hello_files.asm" -recent_file: path: "../hello_files.asm" -recent_file: path: "hello_slices.asm" -recent_file: path: "hello_nasm.asm" -recent_file: path: "../asm" -recent_file: path: "../../../../dev/raddbg/minkernel/crts/ucrt/src/appcrt/startup/abort.cpp" -recent_file: path: "../../../vefontcache-odin/backend/sokol/backend_sokol.odin" -recent_file: path: "../../../vefontcache-odin/examples/sokol_demo/sokol_demo.odin" -recent_file: path: "../../../vefontcache-odin/thirdparty/sokol/c/sokol_gfx.h" -recent_file: path: "../../../vefontcache-odin/thirdparty/sokol/c/sokol_log.h" -recent_file: path: "../../../vefontcache-odin/thirdparty/sokol/c/sokol_app.h" -recent_file: path: "D:/a/_work/1/s/src/vctools/crt/vcruntime/src/string/amd64/memcpy.asm" -recent_file: path: "D:/a/_work/1/s/src/vctools/crt/vcruntime/src/string/amd64/memset.asm" -breakpoint: -{ - source_location: "../../../vefontcache-odin/backend/sokol/backend_sokol.odin:66:1" - hit_count: 0 -} -target: -{ - executable: "../../../WATL_Exercise/build/watl.v0.msvc.exe" - working_directory: "../../../WATL_Exercise/C" -} -type_view: -{ - type: Slice_A2_Str8 - expr: "$.slice()" -} -type_view: -{ - type: Slice_UTF8 - expr: "array($.ptr, $.len)" -} -type_view: -{ - type: Slice_WATL_Node - expr: "array($.ptr, $.len)" -} -type_view: -{ - type: Slice_WATL_Tok - expr: "slice($)" -} -type_view: -{ - type: Slice_KT1CX_Cell_Str8 - expr: "slice($)" -} -type_view: -{ - type: Slice_KT1L_Slot_Str8 - expr: "slice($)" -} -target: -{ - executable: "../../build/hello_nasm.exe" - working_directory: "../../build" -} -target: -{ - executable: "../../build/hello_slices.exe" - working_directory: "../../build" -} +recent_file: path: "../../../../Users/Ed/AppData/Roaming/raddbg/default.raddbg_project/recent_file" +recent_file: path: "../../../../Users/Ed/AppData/Roaming/raddbg/default.raddbg_project/recent_file" target: { executable: "../../build/hello_files.exe" - enabled: 1 working_directory: "../../../asm_dip" -} -breakpoint: -{ - source_location: "hello_slices.asm:60:1" - hit_count: 0 -} -breakpoint: -{ - source_location: "hello_files.asm:674:1" - hit_count: 1 -} -breakpoint: -{ - source_location: "hello_files.asm:584:1" - hit_count: 1 -} -breakpoint: -{ - source_location: "hello_files.asm:605:1" - hit_count: 1 + enabled: 1 }