%include "CONSTANTS.h" ; struct WordT{ ; long count ; char * word ; WordT * next; ; } COUNT_OFFSET equ 0 WORD_OFFSET equ 8 NEXT_OFFSET equ 16 RECORD_SIZE equ 24 extern malloc extern free extern STRCMP section .data msgFMT: db `%s occured %ld times\n`,0 section .bss section .text global PRINT_LIST global PRINT_LISTR global NEW_NODE global INSERT_NODE global DELETE_LIST ; ************************************************************** ; recursive print list ; rdi will hold the head of the list PRINT_LISTR push rbp mov rbp, rsp push r12 cmp rdi, 0 je .done mov r12, rdi mov rdi, [r12+NEXT_OFFSET] call PRINT_LISTR mov rdi, msgFMT mov rsi, [r12 + WORD_OFFSET] mov rdx, [r12 + COUNT_OFFSET] call CallPrintf .done: pop r12 pop rbp ret ; ************************************************************** DELETE_LIST: ; rdi will hold the head pointer; ; while r12 != nullptr ; tmp = r12 ; delete tmp->word ; r12 = r12->next ; delete tmp push rbp mov rbp, rsp push r12 mov r12, rdi .top: cmp r12, 0 je .done ; free the string mov rdi, [r12 + WORD_OFFSET] call free ; then free the node mov rdi, r12 ; r12 = r12->next mov r12, [r12 + NEXT_OFFSET] call free jmp .top .done: pop r12 pop rbp ret ; place holder for now. ; Later we will ; increase the count and free the node if the word is in the list ; or insert the word into the list ; ; ; if head == nullptr ; return node ; if node->word < head->word ; node->next = head ; head = node ; else ; head->next = insertNode(head->next, node) ; ************************************************************** INSERT_NODE: ; rdi will hold the head of the list ; rsi will hold the new node ; rax will return the new node push rbp mov rbp, rsp push r12 push r13 mov r12, rdi mov r13, rsi ; if head == nullptr cmp r12, 0 je .NewHead mov rdi, [r12+WORD_OFFSET] mov rsi, [r13+WORD_OFFSET] call STRCMP cmp rax, 0 ; if (head->word < node->word) jl .Recursion ; if (head->word > node->word) jg .BaseCase ;if (head->word == node->word) ; head->count++ inc qword [r12+COUNT_OFFSET] ; free the new node mov rdi, r13 call free ; (return head) mov rax, r12 jmp .done .Recursion: ; INSERT_NODE(head->next, node) mov rdi, [r12+NEXT_OFFSET] mov rsi, r13 call INSERT_NODE ; head->next = insertNode(head->next , node) ; rax will point to the new next node mov [r12+NEXT_OFFSET], rax ; return head mov rax, r12 jmp .done .BaseCase: .NewHead: mov rax, r13 mov [r13 + NEXT_OFFSET], r12 .done: pop r13 pop r12 pop rbp ret ; ************************************************************** NEW_NODE: ; rdi holds a pointer to a string ; rax will hold the address of the new node push rbp mov rbp, rsp ; save the string address push r12 mov r12, rdi mov rdi, RECORD_SIZE call malloc mov qword [rax + COUNT_OFFSET] , 1 mov qword [rax + WORD_OFFSET] , r12 mov qword [rax + NEXT_OFFSET] , 0 pop r12 pop rbp ret ; ************************************************************** PRINT_LIST: ; rdi holds the pointer to the head of the list ; while (rdi != nullptr) { ; cout << rdi->word << " " << rdi->count << endl; ; rdi = rdi->next ; } push rbp mov rbp, rsp ; r12 will hold the pointer (LCV) push r12 push r13 mov r12, rdi .top: cmp r12, 0 je .done ; cout << rdi->word << " occured " << rdi->count mov rdi, msgFMT mov rsi, [r12 + WORD_OFFSET] mov rdx, [r12 + COUNT_OFFSET] mov r13, rsp and rsp, -16 call CallPrintf mov rsp, r13 ; rdi = rdi->next mov r12, [r12 + NEXT_OFFSET]; jmp .top .done: pop r13 pop r12 pop rbp ret