MIPS字符串反转项目求助:swap函数实现及字符串输出问题
Let's break this down step by step to get you un-stuck with your string reversal project!
先拆解你找到的那段参考Swap代码
First off, that code is designed for integer arrays, not character strings (which are byte arrays)—that's why it didn't make sense for your use case. Let's walk through each line:
sll $t1, $a1, 2 # $t1 = $a1 * 4 —— 整数在MIPS占4字节,左移2位等价乘4,计算数组元素的字节偏移 add $t1, $a0,$t1 # $t1 = 数组基地址 + 偏移量,得到第一个待交换整数的内存地址 lb $t0,0($t1) # 从$t1地址加载1字节(注意:这里应该用`lw`加载4字节整数,原代码有误) lb $t2,4($t1) # 加载$t1+4地址的1字节(同样应该用`lw`) sb $t0,0($t1) # 把$t0存回$t1地址(应该用`sw`存4字节) sb $t2,4($t1) # 把$t2存回$t1+4地址(应该用`sw`) jr $ra # 返回调用函数
关于t系列寄存器
$t0-$t9 are MIPS temporary registers—they're meant for storing intermediate values during calculations. You don't need to save their values to the stack when calling other functions (the caller is responsible for saving them if needed), so they're perfect for quick, short-lived data like addresses or loaded bytes here.
This code won't work for your string because strings use 1-byte characters, not 4-byte integers.
适合字符串的Swap函数实现
Since each character in a string is 1 byte, we can simplify the swap logic to operate directly on single bytes. Here are two practical implementations:
方式1:传递字符索引(基于字符串基地址)
Assume $a0 = string base address, $a1 = index of first character, $a2 = index of second character:
swap_char: add $t0, $a0, $a1 # $t0 = address of first character (base + index, 1-byte offset) add $t1, $a0, $a2 # $t1 = address of second character lb $t2, 0($t0) # Load first character into $t2 lb $t3, 0($t1) # Load second character into $t3 sb $t3, 0($t0) # Store second character in first position sb $t2, 0($t1) # Store first character in second position jr $ra # Return to caller
方式2:直接传递字符地址
If you pass the two character addresses directly to $a0 and $a1, the code is even cleaner:
swap_char_addr: lb $t0, 0($a0) lb $t1, 0($a1) sb $t1, 0($a0) sb $t0, 0($a1) jr $ra
如何输出处理后的字符串
In MIPS, you use the syscall instruction to trigger system services. To print a string:
- Load the syscall number
4into$v0(this corresponds to "print string") - Load the base address of your string into
$a0 - Execute
syscall
Example code snippet:
# Assume your reversed string is stored at the `msg` label li $v0, 4 # Set syscall to print string la $a0, msg # Load string address into $a0 syscall # Execute the print operation
完整字符串反转流程参考
To tie it all together, here's a full working framework for reversing "Hello, World" and printing the result:
.data msg: .asciiz "Hello, World" # Original string newline: .asciiz "\n" # Newline for clean output .text main: # Step 1: Calculate string length la $a0, msg jal str_len move $s0, $v0 # $s0 = length of the string # Step 2: Two-pointer reversal la $s1, msg # Left pointer (start of string) add $s2, $s1, $s0 sub $s2, $s2, 1 # Right pointer (last character of string) reverse_loop: bge $s1, $s2, end_reverse # Exit loop when left >= right move $a0, $s1 move $a1, $s2 jal swap_char_addr # Swap characters at pointers add $s1, $s1, 1 # Move left pointer right sub $s2, $s2, 1 # Move right pointer left j reverse_loop end_reverse: # Print reversed string li $v0, 4 la $a0, msg syscall # Print newline li $v0,4 la $a0, newline syscall # Exit program li $v0, 10 syscall # Helper function: Calculate string length ($a0 = string address, returns $v0 = length) str_len: li $v0, 0 len_loop: lb $t0, 0($a0) beq $t0, 0, len_end add $v0, $v0, 1 add $a0, $a0, 1 j len_loop len_end: jr $ra # Swap function using direct addresses swap_char_addr: lb $t0, 0($a0) lb $t1, 0($a1) sb $t1, 0($a0) sb $t0, 0($a1) jr $ra
内容的提问来源于stack exchange,提问作者djjeane

