# Author: Steven Carr
# Program Created: February 2023
# Assembly program that is a C callable function that copies a string
strncpy.s:
    # Start the program
    .globl mystrncpy        
    .text

    # C Callable mystrncpy function
mystrncpy:
    # Save %ebp and set it at the top of the stack                  
    pushl %ebp
    movl %esp, %ebp

    # Save the %ebx register and reset the values of %eax, %ebx, %ecx and %edx
    push %ebx               
    movl $0, %eax           
    movl $0, %ebx           
    movl $0, %ecx           
    movl $0, %edx           

    # Get the first empty string argument, and put it in %ecx
    movl 8(%ebp), %ecx      

    # Get the second argument, the string to copy, and put it in %edx
    movl 12(%ebp), %edx     

    # Get the third argument, the number of characters to be copied, and put it in %eax
    movl 16(%ebp), %eax

    # Start the loop to copy the string
copyLoop:
    # Move the current letter from %edx to %ecx, using %ebx as a go between
    movb (%edx), %ebx       
    movb %ebx, (%ecx)

    # See if the current character was a null character and if so, jump to the end
    cmpb $0x0, (%ecx)       
    je end                  

    # Subtract one from the total number of characters to copy, and then compare that value to zero
    subl $1, %eax           
    cmpb $0, %eax           # If the value in %eax is zero, then there are no more characters to copy, so jump to the end
    je end

    # Increment to the next character to copy and the next empty space to be copied to
    incb %edx              
    incb %ecx              

    # Loop back to the beginning 
    jmp copyLoop            

    # End the program
end:                        
    popl %ebx               # Recover %ebx
    movl 8(%ebp), %ecx       # Move to beginning of string 
    movl $0, %eax           # Reset %eax
    movl %ecx, %eax         # Put the string in %ecx in %eax to return
    movl %ebp, %esp         # Put the start of the stack back with %esp
    popl %ebp               # Recover %ebp
    ret                     # Return to the C function
    .end
