.section .data largest_msg: .asciz "Max: " smallest_msg: .asciz "The smallest number is: " newline: .asciz "\n" temp_input: .space 32 # Buffer for input string largest: .quad 0 smallest: .quad 0 initialized: .byte 0 # Flag to check if smallest/largest are initialized .section .text .globl _start _start: # Initialize the largest and smallest values movq $0, largest movq $0, smallest movb $0, initialized # Mark as uninitialized read_input: # Read a line of input from stdin movq $0, %rax # syscall: read movq $0, %rdi # file descriptor: stdin lea temp_input(%rip), %rsi # buffer to store input movq $32, %rdx # size of input buffer syscall # Check if input is empty (EOF) cmpq $0, %rax je print_results # Null-terminate the input string lea temp_input(%rip), %rdi # Load base address of temp_input addq %rax, %rdi # Add offset to the base address movb $0, (%rdi) # Null-terminate the string # Convert the input string to an integer lea temp_input(%rip), %rsi call string_to_int movq %rax, %rdi # Store integer in %rdi # Check for termination (sentinel value -1) cmpq $-1, %rdi je print_results # Check if largest/smallest are initialized cmpb $0, initialized(%rip) jne compare_values # Initialize largest and smallest with the first input value movq %rdi, largest(%rip) movq %rdi, smallest(%rip) movb $1, initialized(%rip) # Mark as initialized jmp read_input compare_values: # Update the largest value movq largest(%rip), %rax cmpq %rdi, %rax jge check_smallest movq %rdi, largest(%rip) check_smallest: # Update the smallest value movq smallest(%rip), %rax cmpq %rdi, %rax jle read_input movq %rdi, smallest(%rip) jmp read_input print_results: # Print the largest value movq $1, %rax # syscall: write movq $1, %rdi # file descriptor: stdout lea largest_msg(%rip), %rsi movq $5, %rdx # length of message syscall movq largest(%rip), %rax # Load the largest value call print_integer # Print newline movq $1, %rax movq $1, %rdi lea newline(%rip), %rsi movq $1, %rdx syscall # Print the smallest value movq $1, %rax movq $1, %rdi lea smallest_msg(%rip), %rsi movq $25, %rdx syscall movq smallest(%rip), %rax # Load the smallest value call print_integer # Print newline movq $1, %rax movq $1, %rdi lea newline(%rip), %rsi movq $1, %rdx syscall # Exit program movq $60, %rax # syscall: exit xorq %rdi, %rdi syscall string_to_int: # Convert null-terminated string at %rsi to integer in %rax xorq %rax, %rax # Clear %rax (result) xorq %rbx, %rbx # Clear %rbx (temporary register) convert_loop: movb (%rsi), %bl # Load next character cmpb $0, %bl # Check for null terminator je convert_done subb $48, %bl # Convert ASCII to integer imulq $10, %rax # Multiply result by 10 addq %rbx, %rax # Add the current digit incq %rsi # Move to the next character jmp convert_loop convert_done: ret print_integer: # Convert integer in %rax to string and print it pushq %rbp movq %rsp, %rbp subq $16, %rsp movq $10, %rbx # Base 10 divisor xorq %rcx, %rcx # Counter for digits movq %rax, %rdx # Copy number to %rdx # Convert digits to string in reverse order convert_digit: xorq %r8, %r8 # Clear temporary divq %rbx # Divide %rdx by 10, remainder in %rax addb $48, %al # Convert remainder to ASCII movb %al, -1(%rbp,%rcx) # Store digit incq %rcx # Increment digit count testq %rdx, %rdx # Check if quotient is 0 jne convert_digit # Print the digits movq $1, %rax # syscall: write movq $1, %rdi # file descriptor: stdout lea -1(%rbp,%rcx), %rsi # Start of digits movq %rcx, %rdx # Length of string syscall movq %rbp, %rsp popq %rbp ret