diff options
Diffstat (limited to 'assignments/3/max_min.asm')
| -rw-r--r-- | assignments/3/max_min.asm | 158 |
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 + |
