MIPS开发疑问:如何识别比较.word字符串及将参数解析为整数?
Got it, let's break down your MIPS project challenges step by step—this is a common scenario when handling command-line arguments and string-to-integer conversion, so I'll walk you through each part clearly.
.word Memory First, remember that $a1 points to the argv array—each element is a 32-bit pointer to an .asciiz string (the command-line arguments). We’ll define a .word section in the data segment to hold these pointers, then copy them from argv.
Example Code:
.data # Reserve 2 .word slots to store pointers to our two arguments arg_storage: .word 0, 0 # Optional: Storage for parsed integers parsed_int1: .word 0 parsed_int2: .word 0 .text .globl main main: # First, verify we have at least 2 arguments (argc >= 3, since argv[0] is the program name) li $t0, 3 blt $a0, $t0, insufficient_args # Handle error if not enough args # Store pointer to first argument (argv[1]) into arg_storage[0] lw $t1, 4($a1) # argv[1] is at offset 4 (each pointer is 4 bytes) sw $t1, arg_storage # Store pointer to second argument (argv[2]) into arg_storage[1] lw $t1, 8($a1) sw $t1, arg_storage + 4 # Rest of your code goes here (parsing, comparison, etc.) # ... insufficient_args: # Optional: Add error handling (e.g., print message) li $v0, 10 # Exit program syscall
Note: Always validate the argument count first—your program should handle cases where the user doesn’t pass enough args!
.asciiz Strings to Integers (Supporting Negatives) Next, we’ll write a subroutine to convert the string pointers in arg_storage into integers. This needs to handle negative numbers (detecting the - prefix) and validate digit characters.
String-to-Integer Subroutine:
# Subroutine: str_to_int # Input: $a0 = pointer to .asciiz string # Output: $v0 = parsed integer (0 on invalid input) str_to_int: li $v0, 0 # Initialize result to 0 li $t0, 1 # Sign multiplier (1 = positive, -1 = negative) lb $t1, 0($a0) # Load first character # Check if first character is a negative sign li $t2, '-' bne $t1, $t2, parse_digits li $t0, -1 # Set sign to negative addi $a0, $a0, 1 # Move past the '-' to the first digit parse_digits: lb $t1, 0($a0) # Load current character beq $t1, $zero, apply_sign # Exit if we hit the null terminator # Convert ASCII digit to integer (ASCII '0' = 48) sub $t1, $t1, 48 # Validate character is a digit (0-9) blt $t1, 0, invalid_input bgt $t1, 9, invalid_input # Update result: result = (result * 10) + digit mul $v0, $v0, 10 add $v0, $v0, $t1 addi $a0, $a0, 1 # Move to next character j parse_digits invalid_input: li $v0, 0 # Return 0 if invalid character is found apply_sign: mul $v0, $v0, $t0 # Apply the sign to the final result jr $ra # Return to caller
Using the Subroutine in main:
# Parse first argument lw $a0, arg_storage jal str_to_int sw $v0, parsed_int1 # Store the parsed integer # Parse second argument lw $a0, arg_storage + 4 jal str_to_int sw $v0, parsed_int2
.word Storage Since arg_storage holds pointers to .asciiz strings, comparing them means checking the content of those strings. We’ll implement a standard strcmp subroutine to compare two strings.
String Comparison Subroutine:
# Subroutine: strcmp # Input: $a0 = pointer to first string, $a1 = pointer to second string # Output: $v0 = 0 if strings are equal, negative if first < second, positive if first > second strcmp: loop_compare: lb $t0, 0($a0) lb $t1, 0($a1) # Check if both strings have ended (equal) beq $t0, $zero, check_second_end # Check if current characters differ bne $t0, $t1, return_diff # Move to next characters addi $a0, $a0, 1 addi $a1, $a1, 1 j loop_compare check_second_end: # If first string ended, check if second also ended beq $t1, $zero, equal_strings li $v0, -1 # First string is shorter (so "less than" second) jr $ra return_diff: sub $v0, $t0, $t1 # Return difference between characters jr $ra equal_strings: li $v0, 0 jr $ra
Using strcmp in main:
# Compare the two input strings lw $a0, arg_storage lw $a1, arg_storage + 4 jal strcmp # Check result beq $v0, $zero, strings_are_equal # Handle case where strings are different # ... code ... strings_are_equal: # Handle case where strings are identical # ... code ...
Tip: To identify a specific string (e.g., check if an argument is "help"), define the target string in .data and pass its pointer to strcmp alongside the argument pointer.
内容的提问来源于stack exchange,提问作者Matt

