Commit c8ac898

mo khan <mo@mokhan.ca>
2025-01-23 19:09:22
Update the things
1 parent be0232e
assignments/3/Makefile
@@ -16,3 +16,8 @@ manual: max_min.s
 	as --64 -o max_min.o max_min.s
 	ld -o max_min.exe max_min.o
 	./max_min.exe
+
+manual_ai: max_min.asm
+	as --64 -o max_min.o max_min.asm
+	ld -o max_min.exe max_min.o
+	./max_min.exe
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
+
assignments/3/max_min.s
@@ -2,11 +2,11 @@
 
 	.text
 _start:
-	# write(1, message, 13)
+	# write(1, greeting, 16)
 	mov     $1, %rax                # system call 1 is write
 	mov     $1, %rdi                # file handle 1 is stdout
-	mov     $message, %rsi          # address of string to output
-	mov     $13, %rdx               # number of bytes
+	mov     $greeting, %rsi          # address of string to output
+	mov     $16, %rdx               # number of bytes
 	syscall                         # invoke operating system to do the write
 
 	# read(0, input, 3)
@@ -16,6 +16,27 @@ _start:
 	mov     $4, %rdx                # number of bytes
 	syscall                         # invoke operating system to do the write
 
+	# write(1, max_message, 4)
+	mov     $1, %rax                # system call 1 is write
+	mov     $1, %rdi                # file handle 1 is stdout
+	mov     $max_message, %rsi      # address of string to output
+	mov     $5, %rdx                # number of bytes
+	syscall                         # invoke operating system to do the write
+
+	# write(1, input, 4)
+	mov     $1, %rax                # system call 1 is write
+	mov     $1, %rdi                # file handle 1 is stdout
+	mov     $input, %rsi            # address of string to output
+	mov     $4, %rdx                # number of bytes
+	syscall                         # invoke operating system to do the write
+
+	# write(1, min_message, 4)
+	mov     $1, %rax                # system call 1 is write
+	mov     $1, %rdi                # file handle 1 is stdout
+	mov     $min_message, %rsi      # address of string to output
+	mov     $5, %rdx                # number of bytes
+	syscall                         # invoke operating system to do the write
+
 	# write(1, input, 4)
 	mov     $1, %rax                # system call 1 is write
 	mov     $1, %rdi                # file handle 1 is stdout
@@ -29,5 +50,9 @@ _start:
 	syscall                         # invoke operating system to exit
 
 	.data
-message: .ascii  "Hello, world\n"
+greeting: .ascii  "Enter numbers: \n"
+max_message: .ascii  "Max: "
+min_message: .ascii  "Min: "
 input:	.word 0
+max: .word 0
+min: .word 0
assignments/3-solution.md
@@ -6,8 +6,16 @@ Choose ONE exercise each from Chapters 6, 7, and 8
 
 Chapter 6:
 
-> 13. Write a complete assembly language program (including all necessary pseudo-ops) that reads in a series of integers, one at a time, and outputs the largest and smallest values. The input will consist of a list of integer values
+> 13. Write a complete assembly language program (including all necessary
+> pseudo-ops) that reads in a series of integers, one at a time, and outputs
+> the largest and smallest values. The input will consist of a list of integer
+> values
 
+```assembly
+!include assignments/3/max_min.s
+```
+
+<!--
 I wrote the following C code and then used the GNU C Compiler to convert the C
 code into Assembly code for my machine. Below is the C code, compiler command,
 and final assembly code.
@@ -26,6 +34,7 @@ main.s
 ```assembly
 !include assignments/3/main.s
 ```
+-->
 
 Chapter 7:
 
@@ -129,3 +138,9 @@ $ ruby caesar.rb
 | Ciphertext      | RTAJ TZY FY IFBS                                    |
 | Plaintext       | MOVE OUT AT DAWN                                    |
 ```
+
+References:
+
+* https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
+* https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/as_7.html
+* https://cs.lmu.edu/~ray/notes/gasexamples/
3431709-assignment-3.pdf
Binary file
3431709-assignment-4.pdf
Binary file