From 710e161e07a54fee0b98e43ec8298ef241b36833 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Fri, 2 Aug 2024 11:52:50 +0800 Subject: [PATCH] Add non newline int printer and array printer --- src/chunk_packer.asm | 4 +- src/chunk_unpacker.asm | 4 +- src/data/logger.asm | 19 ++- src/logger.asm | 210 ++++++++++++++++++++++++++++++++- src/macros.asm | 2 +- src/on_game.asm | 4 +- src/on_packet.asm | 8 +- src/on_system.asm | 4 +- src/packer.asm | 2 +- src/packet_packer.asm | 2 +- src/receive_control.asm | 4 +- src/teeworlds_asmr.asm | 2 +- src/udp.asm | 6 +- tests/packet_pack_int_test.asm | 8 ++ tests/print_int_array_test.asm | 20 ++++ 15 files changed, 267 insertions(+), 32 deletions(-) create mode 100644 tests/print_int_array_test.asm diff --git a/src/chunk_packer.asm b/src/chunk_packer.asm index 2fe0015..9f9bdd6 100644 --- a/src/chunk_packer.asm +++ b/src/chunk_packer.asm @@ -94,13 +94,13 @@ pack_chunk_header: .pack_chunk_header_error_seq: print s_unsupported_seq_size mov rax, [connection_sequence] - call print_uint32 + call println_uint32 exit 1 .pack_chunk_header_error_size: print s_unsupported_chunk_size mov rax, rdi - call print_uint32 + call println_uint32 exit 1 .pack_chunk_header_end: diff --git a/src/chunk_unpacker.asm b/src/chunk_unpacker.asm index feb59ac..26b7863 100644 --- a/src/chunk_unpacker.asm +++ b/src/chunk_unpacker.asm @@ -17,12 +17,12 @@ print_chunk_header: print s_size mov rax, 0 mov eax, [chunk_header_size] - call print_uint32 + call println_uint32 print s_sequence mov rax, 0 mov eax, [chunk_header_sequence] - call print_uint32 + call println_uint32 is_chunk_flag CHUNKFLAG_VITAL je .print_chunk_header_vital diff --git a/src/data/logger.asm b/src/data/logger.asm index 581d92b..f19a91d 100644 --- a/src/data/logger.asm +++ b/src/data/logger.asm @@ -1,9 +1,12 @@ -char_newline db 0x0a -char_space db 0x20 -char_dot db '.' -char_minus db '-' -char_single_quote db 0x27 -char_double_quote db 0x22 +char_newline db 0x0a +char_space db 0x20 +char_dot db '.' +char_minus db '-' +char_single_quote db 0x27 +char_double_quote db 0x22 +char_comma db ',' +char_open_bracket db '[' +char_close_bracket db ']' s_dbg_rax_digit db "[debug] value of rax is: " l_s_dbg_rax_digit equ $ - s_dbg_rax_digit @@ -20,3 +23,7 @@ s_string1 db "[system] string1: '" l_s_string1 equ $ - s_string1 s_string2 db "[system] string2: '" l_s_string2 equ $ - s_string2 + +s_supported_ints db "[logger] supported int sizes are 1, 2 and 4 but got: " +l_s_supported_ints equ $ - s_supported_ints + diff --git a/src/logger.asm b/src/logger.asm index 5ce0836..a2e8848 100644 --- a/src/logger.asm +++ b/src/logger.asm @@ -1,6 +1,116 @@ ; vim: set tabstop=4:softtabstop=4:shiftwidth=4 ; vim: set expandtab: +print_any_int: + ; print_any_int [rax] [rdi] + ; rax = int pointer + ; rdi = size in bytes + ; + ; example: + ; mov rbp, rsp + ; sub rsp, 20 + ; mov byte [rbp-20], 22 + ; lea rax, [rbp-20] + ; mov rdi, 1 + ; call print_any_int + ; mov rsp, rbp + ; + ; mov rbp, rsp + ; sub rsp, 20 + ; mov word [rbp-20], 666 + ; lea rax, [rbp-20] + ; mov rdi, 2 + ; call print_any_int + ; mov rsp, rbp + ; + push_registers + + ; int pointer + mov r9, rax + + mov rax, 0 + + cmp rdi, 1 + je .print_any_int_size_1 + + cmp rdi, 2 + je .print_any_int_size_2 + + cmp rdi, 4 + je .print_any_int_size_4 + + jmp .print_any_int_size_error + +.print_any_int_size_1: + mov byte al, [r9] + call print_int32 + jmp .print_any_int_end +.print_any_int_size_2: + mov word ax, [r9] + call print_int32 + jmp .print_any_int_end +.print_any_int_size_4: + mov dword eax, [r9] + call print_int32 + jmp .print_any_int_end + +.print_any_int_size_error: + print s_supported_ints + mov rax, rdi + call println_int32 + exit 1 + +.print_any_int_end: + + pop_registers + ret + +%macro print_int_array 3 + ; print_int_array [array buffer] [element size] [array size] + push_registers + mov rbp, rsp + + ; allocate 1 64 bit register and for the pointer + ; and 2 32 bit register for the integers + sub rsp, 16 + + ; buffer + mov [rbp-16], %1 + + ; this matches so the pointer move worked fine + ; mov rax, [rbp-14] + ; dbg_hexdump_reg rax + + ; element size + mov dword [rbp-8], %2 + + ; array size + mov dword [rbp-4], %3 + + call print_open_bracket + + mov ecx, 0 + %%loop_elements: + inc ecx + + ; 64 bit pointer to integer + mov rax, [rbp-16] + ; 32 bit element size + mov rdi, 0 + mov dword edi, [rbp-8] ; printed and verified to be 1 + call print_any_int + + call print_comma + + cmp ecx, [rbp-4] + jl %%loop_elements + + call print_close_bracket + + mov rsp, rbp + pop_registers +%endmacro + print_newline: push_registers @@ -13,6 +123,42 @@ print_newline: pop_registers ret +print_comma: + push_registers + + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, char_comma + mov rdx, 1 + syscall + + pop_registers + ret + +print_open_bracket: + push_registers + + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, char_open_bracket + mov rdx, 1 + syscall + + pop_registers + ret + +print_close_bracket: + push_registers + + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, char_close_bracket + mov rdx, 1 + syscall + + pop_registers + ret + print_minus: push_registers @@ -61,7 +207,7 @@ print_space: pop_registers ret -dbg_print_uint32: +dbg_println_uint32: ; dbg_print_num [rax] ; ; prints given arg as uint32 turned into a string @@ -71,14 +217,68 @@ dbg_print_uint32: print s_dbg_rax_digit - ; pop of rax to pass it on to print_uint32 + ; pop of rax to pass it on to println_uint32 pop_registers - call print_uint32 + call println_uint32 call print_newline ret +; newline version + +println_int32: + ; print_int32 [rax] + cmp rax, 0 + jge .println_int32_positive +.println_int32_negative: + call print_minus + neg rax +.println_int32_positive: + call println_uint32 + ret + +println_uint32: + ; println_uint32 [rax] + ; + ; has a sub label toascii_digit + ; and prints the given value in rax + ; as a digit to stdout + ; https://stackoverflow.com/a/46301894/6287070 + push_registers + + mov ecx, 0xa ; base 10 + push rcx ; ASCII newline '\n' = 0xa = base + mov rsi, rsp + sub rsp, 16 ; not needed on 64-bit Linux, the red-zone is big enough. Change the LEA below if you remove this. + +;;; rsi is pointing at '\n' on the stack, with 16B of "allocated" space below that. +.println_uint32_toascii_digit: ; do { + xor edx, edx + div ecx ; edx=remainder = low digit = 0..9. eax/=10 + ;; DIV IS SLOW. use a multiplicative inverse if performance is relevant. + add edx, '0' + dec rsi ; store digits in MSD-first printing order, working backwards from the end of the string + mov [rsi], dl + + test eax,eax ; } while(x); + jnz .println_uint32_toascii_digit +;;; rsi points to the first digit + + + mov eax, SYS_WRITE + mov edi, STDOUT + ; pointer already in RSI ; buf = last digit stored = most significant + lea edx, [rsp+16 + 1] ; yes, it's safe to truncate pointers before subtracting to find length. + sub edx, esi ; RDX = length = end-start, including the \n + syscall ; write(1, string /*RSI*/, digits + 1) + + add rsp, 24 ; (in 32-bit: add esp,20) undo the push and the buffer reservation + + pop_registers + ret + +; no newline version print_int32: ; print_int32 [rax] @@ -92,7 +292,7 @@ print_int32: ret print_uint32: - ; print_uint32 [rax] + ; println_uint32 [rax] ; ; has a sub label toascii_digit ; and prints the given value in rax @@ -122,7 +322,7 @@ print_uint32: mov eax, SYS_WRITE mov edi, STDOUT ; pointer already in RSI ; buf = last digit stored = most significant - lea edx, [rsp+16 + 1] ; yes, it's safe to truncate pointers before subtracting to find length. + lea edx, [rsp+16] ; yes, it's safe to truncate pointers before subtracting to find length. sub edx, esi ; RDX = length = end-start, including the \n syscall ; write(1, string /*RSI*/, digits + 1) diff --git a/src/macros.asm b/src/macros.asm index 9fed258..9aa92ad 100644 --- a/src/macros.asm +++ b/src/macros.asm @@ -68,7 +68,7 @@ push_registers print s_dbg_reg_digit mov rax, %1 - call print_uint32 + call println_uint32 pop_registers %endmacro diff --git a/src/on_game.asm b/src/on_game.asm index e26c956..3fc9126 100644 --- a/src/on_game.asm +++ b/src/on_game.asm @@ -11,7 +11,7 @@ on_game_message: mov r10, rdi print s_got_game_msg_with_id - call print_uint32 + call println_uint32 ; payload to rax mov rax, r10 @@ -21,7 +21,7 @@ on_game_message: print s_unknown_game_msg mov rax, r9 - call print_uint32 + call println_uint32 exit 1 on_game_message_end: ret diff --git a/src/on_packet.asm b/src/on_packet.asm index 3c671f9..2ddaf9c 100644 --- a/src/on_packet.asm +++ b/src/on_packet.asm @@ -24,7 +24,7 @@ on_system_or_game_messages: print s_got_packet_with_chunks mov rax, 0 mov al, [in_packet_header_num_chunks] - call print_uint32 + call println_uint32 ; rcx is the offset in bytes pointer mov rcx, 0 @@ -80,18 +80,18 @@ on_system_or_game_messages: .on_system_or_game_messages_loop_error_end_of_data: ; rax is offset print s_parser_bytes_red - call print_uint32 + call println_uint32 ; r10 is payload size print s_received_bytes mov rax, r10 - call print_uint32 + call println_uint32 print s_got_end_of_packet_with_chunks_left mov rax, 0 mov byte al, [in_packet_header_num_chunks] sub al, bl - call print_uint32 + call println_uint32 exit 1 .on_system_or_game_messages_loop_end: diff --git a/src/on_system.asm b/src/on_system.asm index 6a7bcef..912257d 100644 --- a/src/on_system.asm +++ b/src/on_system.asm @@ -11,7 +11,7 @@ on_system_message: mov r10, rdi print s_got_system_msg_with_id - call print_uint32 + call println_uint32 ; payload to rax mov rax, r10 @@ -21,7 +21,7 @@ on_system_message: print s_unknown_system_msg mov rax, r9 - call print_uint32 + call println_uint32 exit 1 on_system_message_end: diff --git a/src/packer.asm b/src/packer.asm index a105867..7e037bf 100644 --- a/src/packer.asm +++ b/src/packer.asm @@ -14,7 +14,7 @@ print s_packer_size mov eax, [packer_size] - call print_uint32 + call println_uint32 pop rax %endmacro diff --git a/src/packet_packer.asm b/src/packet_packer.asm index 34a6633..a042eb5 100644 --- a/src/packet_packer.asm +++ b/src/packet_packer.asm @@ -66,7 +66,7 @@ send_packet: push rax print s_sending_packet_with_size mov rax, rdi - call print_uint32 + call println_uint32 pop rax diff --git a/src/receive_control.asm b/src/receive_control.asm index ded7626..ad833ab 100644 --- a/src/receive_control.asm +++ b/src/receive_control.asm @@ -49,7 +49,7 @@ on_ctrl_message: print s_got_ctrl_msg mov al, [udp_recv_buf + PACKET_HEADER_LEN] - call print_uint32 + call println_uint32 cmp al, MSG_CTRL_TOKEN je on_ctrl_msg_token @@ -59,7 +59,7 @@ on_ctrl_message: je on_ctrl_msg_close print s_unknown_ctrl_msg - call print_uint32 + call println_uint32 on_ctrl_message_end: pop_registers ; pushed in on_ctrl_message diff --git a/src/teeworlds_asmr.asm b/src/teeworlds_asmr.asm index 4d75b9e..2b032b4 100644 --- a/src/teeworlds_asmr.asm +++ b/src/teeworlds_asmr.asm @@ -151,7 +151,7 @@ print_udp: ; [client] len: %d print s_len mov rax, [udp_read_len] - call print_uint32 + call println_uint32 call on_packet ret diff --git a/src/udp.asm b/src/udp.asm index 4a00182..1b8fb93 100644 --- a/src/udp.asm +++ b/src/udp.asm @@ -15,7 +15,7 @@ open_socket: mov [socket], rax print s_got_file_desc mov rax, [socket] - call print_uint32 + call println_uint32 pop_registers ret @@ -47,14 +47,14 @@ recv_udp: ; debug print print s_received_bytes mov rax, [udp_read_len] - call print_uint32 + call println_uint32 jmp .recv_udp_end .recv_udp_error: neg rax cmp rax, EWOULDBLOCK je .recv_udp_end print s_udp_error - call print_uint32 + call println_uint32 .recv_udp_end: pop_registers ret diff --git a/tests/packet_pack_int_test.asm b/tests/packet_pack_int_test.asm index 8cf84c1..a97fa75 100644 --- a/tests/packet_pack_int_test.asm +++ b/tests/packet_pack_int_test.asm @@ -13,6 +13,10 @@ _start: packet_packer_pack_int eax mov eax, 1 packet_packer_pack_int eax + mov r9d, 9 + packet_packer_pack_int r9d + mov r9d, 2 + packet_packer_pack_int r9d mov byte al, [udp_send_buf + PACKET_HEADER_LEN + 0] assert_al_eq 0x01 @@ -34,6 +38,10 @@ _start: assert_al_eq 0x00 mov byte al, [udp_send_buf + PACKET_HEADER_LEN + 9] assert_al_eq 0x01 + mov byte al, [udp_send_buf + PACKET_HEADER_LEN + 10] + assert_al_eq 0x09 + mov byte al, [udp_send_buf + PACKET_HEADER_LEN + 11] + assert_al_eq 0x02 exit 0 diff --git a/tests/print_int_array_test.asm b/tests/print_int_array_test.asm new file mode 100644 index 0000000..24e1802 --- /dev/null +++ b/tests/print_int_array_test.asm @@ -0,0 +1,20 @@ +%include "tests/assert.asm" + +_start: + ; no asserts just checking if we crash or not + + ; stack allocated array of 3 elements + ; every element is a one byte integer + mov rbp, rsp + sub rsp, 3 + mov byte [rbp-3], 0x01 + mov byte [rbp-2], 0x02 + mov byte [rbp-1], 0x02 + + ; rax=buf 1=element size 3=array size + lea rax, [rbp-3] + + print_int_array rax, 1, 3 + + mov rsp, rbp + exit 0