preList.asm

URL: https://mirkwood.cs.edinboro.edu/~bennett/class/cmsc3100/spring2026/notes/files/code/soln/preList.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
     FileName: db `ocap.txt`,0
     fd: dq 0
     DBG_FMT1: db `%s has %ld characters\n`,0

     stringLine: db `"%s"\n`,0;
      
section .bss

section .text

global main
main:

    ;
    ; open(inFile)
    ; string * ptr = getWord(inFile)
    ; while (ptr != nullptr) {
    ;    cout << *ptr;
    ;    free (ptr)
    ;    ptr =  getWord(inFile);
    ; }

    ; open the file
    mov rax, SYS_OPEN
    mov rdi, FileName
    mov rsi, O_RDONLY
    syscall

    mov [fd], rax

top:

    ; grab a word from the file
    call GET_WORD

    ; save the address of the word.
    mov r12, rax

    ; if we got a 0 back, we are at the end of file.
    cmp rax, 0
    je .READ_done

    ; print it out to prove we got it
    mov rdi, stringLine
    mov rsi, rax
    call CallPrintf

    ; free the memory that holds the word
    mov rdi, r12
    call free

    jmp top

.READ_done:

done:

    mov rax, SYS_CLOSE
    mov rdi, [fd] 
    syscall

    jmp Exit

; cmpute 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 
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 rdi, [fd]
    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