寄存器名称映射异常,ADD指令源寄存器标识错误排查请求
问题排查:源寄存器名称显示错误
问题现象
运行程序处理ADD指令时,源寄存器名称显示错误:预期显示s0(2)和s1(16),实际却显示s2(2)和t8(16),但寄存器数值和最终计算结果正确。
相关代码片段
int reg_index; if (strncmp(dst, "s", 1) == 0 && strlen(dst) == 2 && dst[1] >= '0' && dst[1] <= '7') { reg_index = dst[1] - '0'; } else if (strncmp(dst, "t", 1) == 0 && strlen(dst) == 2 && dst[1] >= '0' && dst[1] <= '9') { reg_index = dst[1] - '0'; } else if (strcmp(dst, "v0") == 0) { reg_index = V0; } else { printf("Error in line %d: Invalid destination register\n", line_number); return; } printf("(line %d) %s %s %s %s\n", line_number, opcode, dst, src1, src2); printf("32233282> %s %s(%d) to %s(%d) and changed %s to %d\n", opcode, register_names[val1], val1, register_names[val2], val2, register_names[reg_index], result); registers[reg_index] = result; } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <filename>\n", argv[0]); return 1; }
编译运行命令
gcc -o 322233282 32382.c ./32233282 testcase1.txt
测试用例(testcase1.txt)
LW s0 0x2 LW s1 0x10 ADD v0 s0 s1 NOP
输出对比
预期输出:
(line 1) LW s0 0x2 32233282> Loaded 2 to s0 (line 2) LW s1 0x10 32233282> Loaded 16 to s1 (line 3) ADD v0 s0 s1 32233282> ADD s0(2) to s1(16) and changed v0 to 18 18
实际输出:
(line 1) LW s0 0x2 32233282> Loaded 2 to s0 (line 2) LW s1 0x10 32233282> Loaded 16 to s1 (line 3) ADD v0 s0 s1 32233282> ADD s2(2) to t8(16) and changed v0 to 18 18
问题根源
- 源寄存器解析逻辑缺失:代码仅实现了目标寄存器
dst的索引转换,未对源寄存器src1、src2做名称到索引的解析。 - 索引与数值混淆:输出语句中错误地将寄存器存储的数值(如
s0的值2)作为register_names数组的索引,导致取到错误的寄存器名称(如register_names[2]对应s2)。
修复方案
1. 编写通用寄存器解析函数
实现一个函数统一处理寄存器名称到索引的转换,匹配你的register_names数组布局:
int get_reg_index(const char *reg_name) { // 处理s类寄存器(s0-s7) if (strncmp(reg_name, "s", 1) == 0 && strlen(reg_name) == 2 && reg_name[1] >= '0' && reg_name[1] <= '7') { return reg_name[1] - '0'; // 若register_names[0]对应s0,直接返回数字部分 } // 处理t类寄存器(t0-t9) else if (strncmp(reg_name, "t", 1) == 0 && strlen(reg_name) == 2 && reg_name[1] >= '0' && reg_name[1] <= '9') { int num = reg_name[1] - '0'; return num <=7 ? 8 + num : 24 + (num-8); // 匹配MIPS寄存器布局,可根据实际数组调整 } // 处理v0寄存器 else if (strcmp(reg_name, "v0") == 0) { return V0; // 确保V0宏定义对应正确索引 } // 可补充其他寄存器类型的解析逻辑 return -1; // 返回-1表示无效寄存器 }
2. 解析源寄存器并修正输出逻辑
在ADD指令处理部分,添加源寄存器的解析,并修正输出语句:
// 解析源寄存器索引 int src1_idx = get_reg_index(src1); int src2_idx = get_reg_index(src2); if (src1_idx == -1 || src2_idx == -1) { printf("Error in line %d: Invalid source register\n", line_number); return; } // 获取源寄存器的数值 int val1 = registers[src1_idx]; int val2 = registers[src2_idx]; // 修正后的输出语句 printf("32233282> %s %s(%d) to %s(%d) and changed %s to %d\n", opcode, register_names[src1_idx], val1, register_names[src2_idx], val2, register_names[reg_index], result);
说明
注意:get_reg_index函数中的索引值需要完全匹配你的register_names数组的实际顺序,若你的数组布局与示例不同,需对应调整返回值。
内容的提问来源于stack exchange,提问作者23 이승훈
相关产品推荐
相关产品推荐

