stringLib.asm

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc3100/spring2026/notes/files/code/list/stringLib.asm
 
%include "CONSTANTS.h"

O_RDONLY equ 0
SYS_OPEN equ 2
SYS_CLOSE equ 3

extern malloc
extern free

MAX_WORD_SIZE equ 100
extern GetString

section .data
      
section .bss

section .text

global STRLEN
global STRCPY
global GET_WORD
global STRCMP

;*********************************************************************
; determine if two strings are the same.
;  -1       0     1 depending on if the first is
; smaller equal larger
; it will compare each letter the first with a different letter is smaller
;   and < ant
; or the first to end is smaller
;   and < andrew
;
; rdi will hold a pointer to the first string
; rsi will hold a pointer to the second string
; the result will be returned in rax

STRCMP:
    push rbp
    mov rbp, rsp

    ; r12 will loop through string a
    ; r13 will loop through string b
    ; r14 will hold [r13] for comparison, no memory/memory comparison
    push r12
    push r13
    push r14

    ; set the default answer to be the same
    mov rax, 0

    ;  point at the beginning of each string
    ; I guess I coudl have used  rdi and rsi.

    mov r12, rdi
    mov r13, rsi

.top:
    ; if we are at the end of string A, stop
    cmp byte[r12], 0
    je  .stringAEnd

    ; if we are at the end of string B stop
    cmp byte[r13],0
    je  .bSmall

    mov r14b, byte [r12]
    cmp r14b, byte [r13]

    ; if a is smaller, stop
    jl  .aSmall
    ; if b is smaller stop
    jg  .bSmall

    inc r12
    inc r13

    jmp .top


.stringAEnd:
    ; a might be a the end, is b?
    cmp byte[r13], 0

    ; yep they are the same string
    je .done

    ; nope, a is smaller


.aSmall:
    mov rax, -1
    jmp .done

.bSmall:
    mov rax, 1

.done:

    pop r14
    pop r13
    pop r12

    pop rbp
    ret

;*********************************************************************
; compute the length of the string pointed to by rdi
; leaf routine, no stack messing required
;   rdi points to the base address
STRLEN:
   ; r8 is a pointer into the array
   mov r8, rdi

   ; rax is the count, number of characters
   mov rax, 0

.top:
   ; stop when it hits a 0 (null)
   cmp byte [r8], 0
   je .done

   inc r8
   inc rax
   jmp .top

.done:
   ret;

;*********************************************************************
; make a copy of a string
;
; rdi holds the new memory, assume this is sufficient
; rsi holds the buffer we want to copy there
STRCPY:
;
;   while (src[i] = nullptr) {
;     dest[i] = src[i]
;     ++i
;
.top:
   cmp byte[rsi], 0
   je .done

   mov r8b, [rsi]
   mov [rdi], r8b

   inc rdi
   inc rsi
   
   jmp .top


.done: 
    mov byte [rdi] , 0

    ret

;*********************************************************************

; this will read a word
; allocate memory for it
; stick it into that memory
; and return the pointer to the memory 

; rdi will hold the file descriptor
GET_WORD:
    push rbp
    mov rbp, rsp

    ; use r13 for the base pointer
    push r13

    ; a local buffer for input
    sub rsp, MAX_WORD_SIZE
    sub rsp, 1

    mov r13, rsp


    ; I will use r12 for stack pointer allignment
    push r12

    ; use r14 as temporary storage
    push r14

    ; grab the string from the input
    mov rsi, r13
    mov rdx, MAX_WORD_SIZE

    ; a trick to properly align the stack
    mov r12, rsp
    and rsp, -16
    call GetString
    mov rsp, r12

    ; if we are at the end of the file, return a NULL
    cmp rax, 1
    je  .skip

    mov rax, 0
    jmp .done 

.skip:

    ; compute the string length.
    mov rdi, r13 
    call STRLEN

    ; rax will hold the string length
    ; add one for the null terminator
    inc rax

    ; allocate the memory
    mov rdi, rax
    call malloc

    ; rax now holds the address of the new memory
    mov r14, rax

    mov rdi, rax
    mov rsi, r13
    call STRCPY

    mov rax, r14

.done:

    pop r14
    pop r12

    add rsp, 1
    add rsp, MAX_WORD_SIZE 

    pop r13

    pop rbp
    ret