listLib.asm

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc3100/spring2026/notes/files/code/orderedList/listLib.asm
 
%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