关于将统计数组负数的C函数转换为MIPS汇编的技术疑问
统计数组负数个数的C转MIPS汇编验证与补全
我来帮你一步步梳理这段MIPS汇编的写法,对照你的C函数补全代码并验证正确性。
首先明确你的C函数逻辑:
int countNegatives(int table[] , int n) { int count = 0; int i; for (i=0; i<n; i++) { if (table[i] <0) { count++; } } return count; }
再看你已经编写的MIPS代码片段:
jal countNegatives countNegatives: li $t0, 0 #count = 0 li $t1, 0 #i = 0 loop: bge $t1, $a1, endloop sll $t2, $t1...
完整的正确MIPS汇编实现
# 调用前需确保数组首地址存入$a0,数组长度n存入$a1 jal countNegatives countNegatives: # 规范函数调用:保存返回地址到栈(避免后续操作覆盖$ra) addi $sp, $sp, -4 sw $ra, 0($sp) li $t0, 0 # $t0 对应count,初始化为0 li $t1, 0 # $t1 对应循环变量i,初始化为0 loop: bge $t1, $a1, endloop # 若i >= n,跳至循环结束 sll $t2, $t1, 2 # 计算偏移量:i*4(int类型占4字节) add $t3, $a0, $t2 # 得到table[i]的内存地址:数组首地址+偏移量 lw $t4, 0($t3) # 加载table[i]的值到$t4 bge $t4, $zero, skip # 若元素>=0,跳过count自增操作 addi $t0, $t0, 1 # count++ skip: addi $t1, $t1, 1 # i++ j loop # 回到循环开头 endloop: move $v0, $t0 # MIPS约定返回值存入$v0,将count赋值给$v0 # 恢复栈中的返回地址 lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra # 返回调用处
关键细节解释
- 参数传递:MIPS约定函数前两个参数存在
$a0和$a1,所以table[]对应$a0,n对应$a1,你现有代码中使用$a1的逻辑是正确的。 - 数组元素访问:
sll $t2, $t1, 2是将i左移2位(等价于乘以4),因为MIPS中int占4字节,这样能计算出数组元素的字节偏移量,再与数组首地址$a0相加得到元素的内存地址,最后用lw指令加载值。 - 负数判断:用
bge $t4, $zero, skip判断元素是否非负,若是则跳过count自增,否则执行addi $t0, $t0, 1完成count累加。 - 返回值与栈处理:MIPS规定函数返回值需存入
$v0;另外由于函数通过jal调用,需要将返回地址$ra保存到栈中,避免被后续操作覆盖,函数结束时恢复$ra再用jr $ra返回调用处。
对你现有代码的验证
你写的开头部分逻辑是正确的:初始化$t0为count、$t1为i,循环判断bge $t1, $a1, endloop也符合C函数的循环终止条件。缺失的是数组元素地址计算、值加载、负数判断、count自增以及循环变量递增、返回处理的部分,按照上面的补全后代码就能正常运行。
内容的提问来源于stack exchange,提问作者Nicolas Dahbar
相关产品推荐
相关产品推荐

