summaryrefslogtreecommitdiff
path: root/assignments/3/max_min.asm
diff options
context:
space:
mode:
Diffstat (limited to 'assignments/3/max_min.asm')
-rw-r--r--assignments/3/max_min.asm158
1 files changed, 158 insertions, 0 deletions
diff --git a/assignments/3/max_min.asm b/assignments/3/max_min.asm
new file mode 100644
index 0000000..4487fcc
--- /dev/null
+++ b/assignments/3/max_min.asm
@@ -0,0 +1,158 @@
+.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
+