You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求帮助:将字符串反转C++代码转换为MIPS汇编

将字符串反转的C++代码转换为MIPS汇编指南

别慌!我来一步步带你把这段字符串反转的C++代码转成MIPS汇编,不仅给你完整代码,还会讲清楚每部分的逻辑,让你能看懂背后的思路~

首先,先把你提供的截断代码补全成完整可运行的C++版本,方便对照理解:

#include <iostream> 
using namespace std; 

void reverse(char arr[], int size); 
void swap(char *x, char *y); 

int main() { 
    char array[] = "0123456789"; 
    cout << array << endl; 
    reverse(array, 10); // 字符串长度为10(不含终止符'\0')
    cout << array << endl; 
    return 0; 
}

void reverse(char arr[], int size) {
    int start = 0;
    int end = size - 1;
    while (start < end) {
        swap(&arr[start], &arr[end]);
        start++;
        end--;
    }
}

void swap(char *x, char *y) {
    char temp = *x;
    *x = *y;
    *y = temp;
}

接下来我们拆解成MIPS汇编,分.data(数据段)和.text(代码段)两部分实现:

1. .data 数据段:存储字符串和常量

这部分用来存放我们要反转的字符串以及换行符,MIPS用.asciiz指令定义带终止符的字符串:

.data
    str: .asciiz "0123456789"   # 待反转的字符串,自动追加'\0'终止符
    newline: .asciiz "\n"       # 换行符,用于输出时换行

2. .text 代码段:主程序与函数实现

main函数:程序入口

负责输出原字符串、调用反转函数、输出结果并退出程序:

.text
    .globl main  # 声明main为全局入口
main:
    # 输出原字符串
    li $v0, 4           # MIPS系统调用号4:输出字符串
    la $a0, str         # 将字符串地址加载到$a0(系统调用的参数寄存器)
    syscall             # 执行系统调用

    # 输出换行
    li $v0, 4
    la $a0, newline
    syscall

    # 调用reverse函数:参数1=字符串地址,参数2=字符串长度10
    la $a0, str         # $a0传递第一个参数:字符串地址
    li $a1, 10          # $a1传递第二个参数:字符串长度(不含'\0')
    jal reverse         # 跳转到reverse函数,同时保存返回地址到$ra寄存器

    # 输出反转后的字符串
    li $v0, 4
    la $a0, str
    syscall

    # 输出换行
    li $v0, 4
    la $a0, newline
    syscall

    # 退出程序
    li $v0, 10          # 系统调用号10:退出程序
    syscall

reverse函数:实现双指针反转逻辑

用start和end两个指针从两端向中间遍历,交换对应位置的字符:

reverse:
    # 建立栈帧:保存需要保留的寄存器(MIPS中$s寄存器是被调用者保存的)
    addi $sp, $sp, -16  # 栈指针减16,分配4个寄存器的存储空间(每个4字节)
    sw $ra, 12($sp)     # 保存返回地址$ra到栈偏移12的位置
    sw $s2, 8($sp)      # 保存字符串地址(来自$a0)到$s2
    sw $s1, 4($sp)      # 保存end指针到$s1
    sw $s0, 0($sp)      # 保存start指针到$s0

    move $s2, $a0       # 将字符串地址从$a0移到$s2保存
    li $s0, 0           # 初始化start=0
    sub $s1, $a1, 1     # 初始化end=size-1

reverse_loop:
    bge $s0, $s1, reverse_end  # 如果start >= end,跳出循环

    # 准备swap函数的参数:&arr[start] 和 &arr[end]
    add $t0, $s2, $s0   # $t0 = arr地址 + start偏移(char占1字节,直接相加)
    add $t1, $s2, $s1   # $t1 = arr地址 + end偏移
    move $a0, $t0       # 传递swap的第一个参数:&arr[start]
    move $a1, $t1       # 传递swap的第二个参数:&arr[end]
    jal swap            # 调用swap函数

    addi $s0, $s0, 1    # start++
    addi $s1, $s1, -1   # end--
    j reverse_loop      # 回到循环开头

reverse_end:
    # 恢复栈帧,返回main函数
    lw $s0, 0($sp)
    lw $s1, 4($sp)
    lw $s2, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16   # 栈指针恢复到初始位置
    jr $ra              # 返回调用者(main)

swap函数:交换两个字符的内容

负责交换两个指针指向的单个字符:

swap:
    # 加载两个指针指向的字符(char是1字节,用lb指令加载)
    lb $t0, 0($a0)      # $t0 = *x(x是第一个参数的地址)
    lb $t1, 0($a1)      # $t1 = *y(y是第二个参数的地址)

    # 交换存储两个字符(用sb指令存储字节)
    sb $t1, 0($a0)      # *x = $t1(把y的内容写到x的地址)
    sb $t0, 0($a1)      # *y = $t0(把x的内容写到y的地址)

    jr $ra              # 返回调用者(reverse函数)

关键知识点说明

  • 栈帧的作用:MIPS中,$s寄存器属于「被调用者保存寄存器」,也就是说如果函数要使用这些寄存器,必须先保存到栈上,函数结束后再恢复;另外$ra(返回地址)也需要保存,因为reverse调用了swap,会覆盖$ra的值。
  • 内存访问指令:因为char是1字节类型,所以用lb(加载字节)和sb(存储字节)指令,而不是处理4字节的lw/sw。
  • 参数传递规则:MIPS通过$a0-$a3寄存器传递函数参数,超过4个参数才会用到栈。这里reverse和swap的参数都在2个以内,直接用$a0和$a1传递。
  • 系统调用:MIPS的系统调用通过$v0寄存器指定调用号,比如4是输出字符串,10是退出程序,执行时调用syscall指令。

内容的提问来源于stack exchange,提问作者djjeane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:17:22