Skip to content

Commit

Permalink
First draft of construct tree (infinite loop bug for now)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChillerDragon committed Aug 3, 2024
1 parent 379a586 commit 4d13f37
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/bss/huffman.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
; m_aNodes array of CNODE structs
huff_nodes resb HUFF_CNODE_SIZE * HUFFMAN_MAX_NODES

; aNodesLeftStorage[HUFFMAN_MAX_SYMBOLS];
huff_nodes_left_storage resb HUFF_CNODE_SIZE * HUFFMAN_MAX_SYMBOLS

; *apNodesLeft[HUFFMAN_MAX_SYMBOLS];
huff_nodes_left resb 4 * HUFFMAN_MAX_SYMBOLS

; m_apDecodeLut array of CNODE structs
huff_decode_lut resb HUFFMAN_LUTSIZE * 8

Expand Down
16 changes: 16 additions & 0 deletions src/data/huffman.asm
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,19 @@ HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET equ 0
HUFF_CCONSTRUCTION_NODE_FREQUENCY_OFFSET equ 2
HUFF_CCONSTRUCTION_NODE_SIZE equ 6

HUFF_FREQ_TABLE dd 1073741824,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186, \
283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176, \
872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19, \
16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68, \
59,66,61,638,71,157,50,46,69,43,11,24,13,19,10,12,12,20,14,9, \
20,20,10,10,15,15,12,12,7,19,15,14,13,18,35,19,17,14,8,5, \
15,17,9,15,14,18,8,10,2173,134,157,68,188,60,170,60,194,62,175,71, \
148,67,167,78,211,67,156,69,1674,90,174,53,147,89,181,51,174,63,163,80, \
167,94,128,122,223,153,218,77,200,110,190,73,174,69,145,66,277,143,141,60, \
136,53,180,57,142,57,158,61,166,112,152,92,26,22,21,28,20,26,30,21, \
32,27,20,17,23,21,30,22,22,21,27,25,17,27,23,18,39,26,15,21, \
12,18,18,27,20,18,15,19,11,17,33,12,18,15,19,18,16,26,17,18, \
9,10,25,22,22,17,20,16,6,16,15,20,14,18,24,335,1517
HUFF_FREQ_TABLE_SIZE equ ($ - HUFF_FREQ_TABLE) / 4
; print_int32_array HUFF_FREQ_TABLE, HUFF_FREQ_TABLE_SIZE

174 changes: 174 additions & 0 deletions src/huffman/construct_tree.asm
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,179 @@
; huff_num_nodes resb 4

_huff_construct_tree:
push_registers
mov rbp, rsp

sub rsp, 4
; int NumNodesLeft = HUFFMAN_MAX_SYMBOLS
mov dword [rbp-4], HUFFMAN_MAX_SYMBOLS

mov rcx, 0
; for(int i = 0; i < HUFFMAN_MAX_SYMBOLS; i++)
._huff_construct_tree_for_loop:
cmp rcx, HUFFMAN_MAX_SYMBOLS
jge ._huff_construct_tree_for_loop_end

mov rbx, rcx
imul rbx, HUFF_CNODE_SIZE
; m_aNodes[i].m_NumBits = 0xFFFFFFFF;
mov dword [huff_nodes + rbx + HUFF_CNODE_NUM_BITS_OFFSET], 0xFFFF_FFFF
; m_aNodes[i].m_Symbol = i;
mov byte [huff_nodes + rbx + HUFF_CNODE_SYMBOL_OFFSET], cl
mov word [huff_nodes + rbx + HUFF_CNODE_LEAF_0_OFFSET], 0xffff
mov word [huff_nodes + rbx + HUFF_CNODE_LEAF_1_OFFSET], 0xffff

; get i offset into aNodesLeftStorage[i]
mov rbx, rcx
imul rbx, HUFF_CCONSTRUCTION_NODE_SIZE

; if(i == HUFFMAN_EOF_SYMBOL)
cmp rcx, HUFFMAN_EOF_SYMBOL
jne ._huff_construct_tree_i_not_eof
mov dword [huff_nodes_left_storage + rbx + HUFF_CCONSTRUCTION_NODE_FREQUENCY_OFFSET], 1
jmp ._huff_construct_tree_for_loop_if_end
._huff_construct_tree_i_not_eof:
; eax = pFrequencies[i]
; r9 = i
mov r9, rcx
; 4 is the size of int / unsigned int
; which is the element size in the freq table array
imul r9, 4
mov rax, 0
mov eax, [HUFF_FREQ_TABLE + r9]
mov dword [huff_nodes_left_storage + rbx + HUFF_CCONSTRUCTION_NODE_FREQUENCY_OFFSET], eax
._huff_construct_tree_for_loop_if_end:

; aNodesLeftStorage[i].m_NodeId = i;
; rbx is still the correct [i] offset
mov word [huff_nodes_left_storage + rbx + HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET], cx

; rax = &aNodesLeftStorage[i];
lea rax, [huff_nodes_left_storage + rbx]

mov rbx, rcx
; 8 is the size of a pointer on 64 bit machines
; huff_nodes_left is an array of pointers
imul rbx, 8
mov qword [huff_nodes_left + rbx], rax

inc rcx
jmp ._huff_construct_tree_for_loop
._huff_construct_tree_for_loop_end:

; m_NumNodes = HUFFMAN_MAX_SYMBOLS;
mov dword [huff_num_nodes], HUFFMAN_MAX_SYMBOLS

; while(NumNodesLeft > 1)
._huff_construct_tree_while_loop:
cmp dword [rbp-4], 1
jle ._huff_construct_tree_while_loop_end

; rax = **ppList
mov rax, huff_nodes_left
; rdi = Size
; rbp-4 is NumNodesLeft
mov rdi, 0
mov edi, [rbp-4]
call _huff_bubble_sort

; m_aNodes[m_NumNodes].m_NumBits = 0;
mov rbx, [rbp-4]
imul rbx, HUFF_CNODE_SIZE
mov dword [huff_nodes + rbx + HUFF_CNODE_NUM_BITS_OFFSET], 0

; r9 is the offset NumNodesLeft into apNodesLeft
mov r9, 0
mov r9d, [rbp-4]
; apNodesLeft is an array of pointers
; so the offset is 8 (pointer size)
imul r9, 8

; m_aNodes[m_NumNodes].m_aLeafs[0] = apNodesLeft[NumNodesLeft-1]->m_NodeId;
; rax = apNodesLeft[NumNodesLeft-1]->m_NodeId;
; NumNodesLeft - 1
mov rsi, [huff_nodes_left + r9 - (1 * 8)] ; get pointer from array
; get 2 byte field from struct at dereferenced value
; ax = unsigned int NodeId
mov rax, 0
mov ax, [rsi + HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET]
mov word [huff_nodes + rbx + HUFF_CNODE_LEAF_0_OFFSET], ax

; m_aNodes[m_NumNodes].m_aLeafs[1] = apNodesLeft[NumNodesLeft-2]->m_NodeId;
; rax = apNodesLeft[NumNodesLeft-2]->m_NodeId;
; NumNodesLeft - 2
mov rsi, [huff_nodes_left + r9 - (2 * 8)] ; get pointer from array
; get 2 byte field from struct at dereferenced value
; ax = unsigned int NodeId
mov rax, 0
mov ax, [rsi + HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET]
mov word [huff_nodes + rbx + HUFF_CNODE_LEAF_1_OFFSET], ax

; apNodesLeft[NumNodesLeft-2]->m_NodeId = m_NumNodes;
mov rax, [huff_nodes_left + r9 - (2 * 8)] ; get pointer from array
add rax, HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET ; ->m_NodeId
mov si, [huff_num_nodes]
mov word [rax], si


; apNodesLeft[NumNodesLeft-2]->m_Frequency = apNodesLeft[NumNodesLeft-1]->m_Frequency + apNodesLeft[NumNodesLeft-2]->m_Frequency;

; r10 = apNodesLeft[NumNodesLeft-1]->m_Frequency
; NumNodesLeft - 1
mov rax, [huff_nodes_left + r9 - (1 * 8)] ; get pointer from array
; get 4 byte field from struct at dereferenced value
; r10d = int m_Frequency
mov r10, 0
mov r10d, [rax + HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET]

; r11 = apNodesLeft[NumNodesLeft-2]->m_Frequency
; NumNodesLeft - 2
mov rax, [huff_nodes_left + r9 - (2 * 8)] ; get pointer from array
; get 4 byte field from struct at dereferenced value
; r10d = int m_Frequency
mov r11, 0
mov r11d, [rax + HUFF_CCONSTRUCTION_NODE_NODE_ID_OFFSET]

; apNodesLeft[NumNodesLeft-1]->m_Frequency + apNodesLeft[NumNodesLeft-2]->m_Frequency;
add r10, r11

; apNodesLeft[NumNodesLeft-2]->m_Frequency = r10
mov rax, [huff_nodes_left + r9 - (2 * 8)] ; get pointer from array
add rax, HUFF_CCONSTRUCTION_NODE_FREQUENCY_OFFSET ; ->m_Frequency
mov dword [rax], r10d

; m_NumNodes++
mov rax, 0
mov eax, [huff_num_nodes]
inc eax
mov [huff_num_nodes], eax

; NumNodesLeft--
dec dword [rbp-4]

jmp ._huff_construct_tree_while_loop
._huff_construct_tree_while_loop_end:

; ebx = m_NumNodes - 1
mov rbx, 0
mov ebx, [huff_num_nodes]
dec ebx

; rax = &m_aNodes[m_NumNodes-1]
imul ebx, HUFF_CNODE_SIZE
lea rax, [huff_nodes + ebx]
; m_pStartNode = &m_aNodes[m_NumNodes-1];
mov qword [huff_start_node], rax

; rax = *pNode (still set)
; rdi = int Bits
mov rdi, 0
; rsi = unsigned Depth
mov rsi, 0
call _huff_setbits_r


mov rsp, rbp
pop_registers
ret

7 changes: 6 additions & 1 deletion src/logger.asm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ print_any_int:
sub rsp, 16

; buffer
mov [rbp-16], %1
mov qword [rbp-16], %1

; this matches so the pointer move worked fine
; mov rax, [rbp-14]
Expand Down Expand Up @@ -121,6 +121,11 @@ print_any_int:
pop_registers
%endmacro

%macro print_int32_array 2
; print_int32_array [array buffer] [array size]
print_int_array %1, 4, %2
%endmacro

print_newline:
push_registers

Expand Down
1 change: 1 addition & 0 deletions tests/huffman_decompress_test.asm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%include "tests/assert.asm"

_start:
; call _huff_construct_tree
exit 0

0 comments on commit 4d13f37

Please sign in to comment.