From 70ce12dc055bfead28d61225ea9bcb5b11a6c242 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Tue, 8 Sep 2026 15:41:37 -0700 Subject: bubblesort the metadata entries during postprocessing since we do this here, we no longer need to worry about doing it during initial entry creation, so that's good. that had been on the mental "maybe later" checklist for a while. the various innovations in entry processing now make it possible to pass through most of the formatting in hex.e, so that's done now (suffix comments that aren't instruction decodings still need to be made to work) there's also a new entry type which will be part of the comment parameter system. that's not fully working yet, but this was a bunch of really subtle debugging, so it makes a good spot to checkpoint at. Force-Push: yes Change-Id: I2aff7276368eaad7e5c280a58834605e294dcd74 --- hex.e | 72 ++++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 27 deletions(-) (limited to 'hex.e') diff --git a/hex.e b/hex.e index fd283ca..d1c4e31 100644 --- a/hex.e +++ b/hex.e @@ -21,88 +21,106 @@ ~ : This is the start routine, the first thing that runs when the ELF loads. ~ : indent current-offset L!' cold-start - ~ The basic registers preserved across syscalls are rbx, rsp, rbp. - ~ To avoid redundant moves, we store the buffer pointer in rbx just once, - ~ and keep it there. We've made sure our load origin fits in 32 bits, so we - ~ can use imm32 for that. We're going to want to do an indirect load from - ~ it, so we can't use rbp for this. + ~ : The basic registers preserved across syscalls are rbx, rsp, rbp. + ~ : To avoid redundant moves, we store the buffer pointer in rbx just once, + ~ : and keep it there. We've made sure our load origin fits in 32 bits, so + ~ : we can use imm32 for that. We're going to want to do an indirect load + ~ : from it, so we can't use rbp for this. L@' buffer L@' origin + :rbx mov-reg64-imm32 + ~ : blank-line current-offset L!' input-loop-start L@' read-byte call-rel-imm32-from-here + ~ : blank-line - ~ If the length is 0, we got EOF. If it's less than zero, we got a read - ~ error. Either way, we exit. This is a signed comparison, as it needs to - ~ be. + ~ : If the length is 0, we got EOF. If it's less than zero, we got a read + ~ : error. Either way, we exit. This is a signed comparison, as it needs to + ~ : be. 0 :rax cmp-reg64-imm8 L@' exit :cc-equal jmp-cc-rel-imm8-from-here L@' read-error :cc-less jmp-cc-rel-imm8-from-here + ~ : blank-line - ~ Now that the length is handled, retrieve the input byte. + ~ : Now that the length is handled, retrieve the input byte. :rbx :rax mov-reg64-indirect-reg64 + ~ : blank-line - ~ If it's space or linefeed, skip it (go back to the loop start). + ~ : If it's space or linefeed, skip it (go back to the loop start). 0x20 :rax cmp-reg64-imm8 ~ ASCII space L@' input-loop-start :cc-equal jmp-cc-rel-imm8-from-here 0x0a :rax cmp-reg64-imm8 ~ ASCII linefeed L@' input-loop-start :cc-equal jmp-cc-rel-imm8-from-here - ~ If it's a comment, skip the whole thing. + ~ : If it's a comment, skip the whole thing. 0x7e :rax cmp-reg64-imm8 ~ ASCII tilde L@' skip-comment :cc-equal jmp-cc-rel-imm8-from-here + ~ : blank-line - ~ Decode the value, or exit with an error. + ~ : Decode the value, or exit with an error. L@' decode-nibble call-rel-imm32-from-here + ~ : blank-line - ~ We use rbp as a place to stash the high nibble. + ~ : We use rbp as a place to stash the high nibble. :rax :rbp mov-reg64-reg64 4 :rbp rol-reg64-imm8 + ~ : blank-line - ~ Now we read another byte. + ~ : Now we read another byte. L@' read-byte call-rel-imm32-from-here + ~ : blank-line - ~ Handle the length. A second hex digit is required here. + ~ : Handle the length. A second hex digit is required here. 0 :rax cmp-reg64-imm8 L@' unexpected-eof :cc-equal jmp-cc-rel-imm8-from-here L@' read-error :cc-less jmp-cc-rel-imm8-from-here + ~ : blank-line - ~ Now that the length is handled, retrieve the input byte. + ~ : Now that the length is handled, retrieve the input byte. :rbx :rax mov-reg64-indirect-reg64 + ~ : blank-line - ~ Decode the value, or exit with an error. + ~ : Decode the value, or exit with an error. L@' decode-nibble call-rel-imm32-from-here + ~ : blank-line - ~ We OR in the low nibble. + ~ : We OR in the low nibble. :rax :rbp or-reg64-reg64 + ~ : blank-line - ~ Output the byte. We reuse the buffer as a place to store it. + ~ : Output the byte. We reuse the buffer as a place to store it. :rbp :rbx mov-indirect-reg64-reg64 :rbx :rsi mov-reg64-reg64 ~ buffer pointer 1 :rdx mov-reg64-imm32 ~ buffer length 1 :rax mov-reg64-imm32 ~ syscall number for sys-write 1 :rdi mov-reg64-imm32 ~ file descriptor 1 is stdout syscall + ~ : blank-line - ~ Back to the start of the loop. + ~ : Back to the start of the loop. L@' input-loop-start jmp-rel-imm8-from-here + ~ : blank-line current-offset L!' skip-comment - ~ Read a byte for the comment. + ~ : Read a byte for the comment. L@' read-byte call-rel-imm32-from-here + ~ : blank-line - ~ Handle the length. We're allowed to end in a comment. + ~ : Handle the length. We're allowed to end in a comment. 0 :rax cmp-reg64-imm8 L@' exit :cc-equal jmp-cc-rel-imm8-from-here L@' read-error :cc-less jmp-cc-rel-imm8-from-here + ~ : blank-line - ~ Now that the length is handled, retrieve the input byte. + ~ : Now that the length is handled, retrieve the input byte. :rbx :rax mov-reg64-indirect-reg64 + ~ : blank-line - ~ If it's linefeed, the comment is over. + ~ : If it's linefeed, the comment is over. 0x0a :rax cmp-reg64-imm8 ~ ASCII linefeed L@' input-loop-start :cc-equal jmp-cc-rel-imm8-from-here + ~ : blank-line - ~ We're still in the comment, keep handling it. + ~ : We're still in the comment, keep handling it. L@' skip-comment jmp-rel-imm8-from-here ~ : deindent ; @@ -119,11 +137,11 @@ ~ : This is the routine named "read-byte". ~ : indent current-offset L!' read-byte - ~ We use self-xor as a concise way to set registers to zero. + ~ : We use self-xor as a concise way to set registers to zero. :rax :rax xor-reg64-reg64 ~ syscall number for sys-read :rdi :rdi xor-reg64-reg64 ~ file descriptor 0 is stdin :rbx :rsi mov-reg64-reg64 ~ buffer pointer - ~ We read one byte at a time, because it makes the loop structure simple. + ~ : We read one byte at a time, because it makes the loop structure simple. 1 :rdx mov-reg64-imm32 ~ buffer length syscall ret -- cgit 1.4.1