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