main
  1.section .data
  2largest_msg: .asciz "Max: "
  3smallest_msg: .asciz "The smallest number is: "
  4newline: .asciz "\n"
  5temp_input: .space 32  # Buffer for input string
  6largest: .quad 0
  7smallest: .quad 0
  8initialized: .byte 0  # Flag to check if smallest/largest are initialized
  9
 10.section .text
 11.globl _start
 12
 13_start:
 14    # Initialize the largest and smallest values
 15    movq $0, largest
 16    movq $0, smallest
 17    movb $0, initialized  # Mark as uninitialized
 18
 19read_input:
 20    # Read a line of input from stdin
 21    movq $0, %rax        # syscall: read
 22    movq $0, %rdi        # file descriptor: stdin
 23    lea temp_input(%rip), %rsi # buffer to store input
 24    movq $32, %rdx       # size of input buffer
 25    syscall
 26
 27    # Check if input is empty (EOF)
 28    cmpq $0, %rax
 29    je print_results
 30
 31    # Null-terminate the input string
 32    lea temp_input(%rip), %rdi   # Load base address of temp_input
 33    addq %rax, %rdi              # Add offset to the base address
 34    movb $0, (%rdi)              # Null-terminate the string
 35
 36    # Convert the input string to an integer
 37    lea temp_input(%rip), %rsi
 38    call string_to_int
 39    movq %rax, %rdi      # Store integer in %rdi
 40
 41    # Check for termination (sentinel value -1)
 42    cmpq $-1, %rdi
 43    je print_results
 44
 45    # Check if largest/smallest are initialized
 46    cmpb $0, initialized(%rip)
 47    jne compare_values
 48
 49    # Initialize largest and smallest with the first input value
 50    movq %rdi, largest(%rip)
 51    movq %rdi, smallest(%rip)
 52    movb $1, initialized(%rip)  # Mark as initialized
 53    jmp read_input
 54
 55compare_values:
 56    # Update the largest value
 57    movq largest(%rip), %rax
 58    cmpq %rdi, %rax
 59    jge check_smallest
 60    movq %rdi, largest(%rip)
 61
 62check_smallest:
 63    # Update the smallest value
 64    movq smallest(%rip), %rax
 65    cmpq %rdi, %rax
 66    jle read_input
 67    movq %rdi, smallest(%rip)
 68    jmp read_input
 69
 70print_results:
 71    # Print the largest value
 72    movq $1, %rax        # syscall: write
 73    movq $1, %rdi        # file descriptor: stdout
 74    lea largest_msg(%rip), %rsi
 75    movq $5, %rdx       # length of message
 76    syscall
 77
 78    movq largest(%rip), %rax   # Load the largest value
 79    call print_integer
 80
 81    # Print newline
 82    movq $1, %rax
 83    movq $1, %rdi
 84    lea newline(%rip), %rsi
 85    movq $1, %rdx
 86    syscall
 87
 88    # Print the smallest value
 89    movq $1, %rax
 90    movq $1, %rdi
 91    lea smallest_msg(%rip), %rsi
 92    movq $25, %rdx
 93    syscall
 94
 95    movq smallest(%rip), %rax  # Load the smallest value
 96    call print_integer
 97
 98    # Print newline
 99    movq $1, %rax
100    movq $1, %rdi
101    lea newline(%rip), %rsi
102    movq $1, %rdx
103    syscall
104
105    # Exit program
106    movq $60, %rax        # syscall: exit
107    xorq %rdi, %rdi
108    syscall
109
110string_to_int:
111    # Convert null-terminated string at %rsi to integer in %rax
112    xorq %rax, %rax       # Clear %rax (result)
113    xorq %rbx, %rbx       # Clear %rbx (temporary register)
114
115convert_loop:
116    movb (%rsi), %bl      # Load next character
117    cmpb $0, %bl          # Check for null terminator
118    je convert_done
119    subb $48, %bl         # Convert ASCII to integer
120    imulq $10, %rax       # Multiply result by 10
121    addq %rbx, %rax       # Add the current digit
122    incq %rsi             # Move to the next character
123    jmp convert_loop
124
125convert_done:
126    ret
127
128print_integer:
129    # Convert integer in %rax to string and print it
130    pushq %rbp
131    movq %rsp, %rbp
132    subq $16, %rsp
133
134    movq $10, %rbx       # Base 10 divisor
135    xorq %rcx, %rcx      # Counter for digits
136    movq %rax, %rdx      # Copy number to %rdx
137
138    # Convert digits to string in reverse order
139convert_digit:
140    xorq %r8, %r8        # Clear temporary
141    divq %rbx            # Divide %rdx by 10, remainder in %rax
142    addb $48, %al        # Convert remainder to ASCII
143    movb %al, -1(%rbp,%rcx)  # Store digit
144    incq %rcx            # Increment digit count
145    testq %rdx, %rdx     # Check if quotient is 0
146    jne convert_digit
147
148    # Print the digits
149    movq $1, %rax        # syscall: write
150    movq $1, %rdi        # file descriptor: stdout
151    lea -1(%rbp,%rcx), %rsi # Start of digits
152    movq %rcx, %rdx      # Length of string
153    syscall
154
155    movq %rbp, %rsp
156    popq %rbp
157    ret
158