
.set STDOUT, 1
.set __NR_write, 1

# ---------- DATA ----------
     .data

# Test strings, try changing them to different strings and re-running
# the program.
str1: 
     .asciz "hello"
str2: 
     .asciz "hello"

# Strings to output to STDOUT if equal or not equao
equal:
     .asciz "equal"

not_equal:
     .asciz "not equal"

# ---------- CODE ----------
     .globl _start
     .text

_start:
    # our strn_cmp function requires that we pass in %rdi and %rsi the address
    # of the strings we want to compare.
    # %rcx will be the length of bytes we want to compare and this will be
    # clarified why when we get to the string comparison function.
    lea     str1, %rdi
    lea     str2, %rsi
    mov     $5, %rcx
    call    strn_cmp
    test    %rax, %rax             # We return 0 if equal -1 if not equal
    jnz     .L_not_equal

    lea     equal, %rdi            # Print strings are equal
    call    print_str

.L_exit:
    mov    $60, %rax
    mov    $0, %rdi
    syscall

.L_not_equal:
    lea    not_equal, %rdi
    call   print_str
    jmp    .L_exit

print_str:
    # Print a string to STDOUT = 1
    # %rdi holds the address of the string
    #
    # We need to find the length of the string first and then print using
    # syscall __NR_write (sys_write) 
    push   %rcx
    push   %rax
    push   %rdx

    xor    %rcx, %rcx
.L_strlen:
    movb   (%rdi, %rcx), %al
    test   %al, %al
    jz     .L_write
    inc    %rcx
    jmp    .L_strlen
.L_write:
    # At this point %rcx holds the length of the null terminated string
    mov    %rcx, %rdx
    mov    %rdi, %rsi
    mov    $STDOUT, %rdi
    mov    $__NR_write, %rax
    syscall

    pop    %rdx
    pop    %rax
    pop    %rcx
    ret

# String comparison utility function with variable length checking
# %rcx is length to check
# %rdi string1
# %rsi string2
# %rax is return
strn_cmp:
    cld
    repe    cmpsb
    jne     .L_strn_cmp_ne
    xor     %rax, %rax
    ret
.L_strn_cmp_ne:
    mov     $-1, %rax
    ret 
