MIPS二进制文件读取与格式转换输出问题求助
MIPS二进制文件读取与格式转换输出问题求助
我正在做计算机架构课程的项目,学习MIPS和汇编语言。这个程序需要读取一个.bin格式的MIPS二进制可执行文件,输出一个人类可读的.txt文件。
我的输入二进制文件(以文本形式展示)是这样的:
00000000010000000000000000000000 00010000000000010000000000000000 01111111111111111110111111111100 00000000000000000000000000000011 00000000000000000000000000000001 00000000000000000000000000000010 00000000000000000000000000000011 00111100000000010001000000000001 00110100001010000000000000000000 00100100000010010000000000000011 00100100000010100000000000000000 00010001010010010000000000000110 10001101000010110000000000000000 00100011101111011111111111111100 10101111101010110000000000000000 00100001000010000000000000000100 00100001010010100000000000000001 00001000000100000000000000000100 00111100000000010001000000000001 00110100001010000000000000000000 00100100000011000000010011010010 10101101000011000000000000000100 00100100000000100000000000001010 00000000000000000000000000001100
我需要把它解码成这样的人类可读.txt文件:
initialPC: 4194304 dataStartAddress: 268500992 initialStackPointer: 2147479548 Number of data items: 3 268500992: 00000000000000000000000000000001 1 268500996: 00000000000000000000000000000010 2 268501000: 00000000000000000000000000000011 3 4194304: 00111100000000010001000000000001 lui $at, 4097 4194308: 00110100001010000000000000000000 ori $t0, $at, 0 4194312: 00100100000010010000000000000011 addiu $t1, $zero, 3 4194316: 00100100000010100000000000000000 addiu $t2, $zero, 0 4194320: 00010001010010010000000000000110 beq $t2, $t1, 6 4194324: 10001101000010110000000000000000 lw $t3, 0($t0) 4194328: 00100011101111011111111111111100 addi $sp, $sp, -4 4194332: 10101111101010110000000000000000 sw $t3, 0($sp) 4194336: 00100001000010000000000000000100 addi $t0, $t0, 4 4194340: 00100001010010100000000000000001 addi $t2, $t2, 1 4194344: 00001000000100000000000000000100 j 4194320 4194348: 00111100000000010001000000000001 lui $at, 4097 4194352: 00110100001010000000000000000000 ori $t0, $at, 0 4194356: 00100100000011000000010011010010 addiu $t4, $zero, 1234 4194360: 10101101000011000000000000000100 sw $t4, 4($t0) 4194364: 00100100000000100000000000001010 addiu $v0, $zero, 10 4194368: 00000000000000000000000000001100 syscall
之前我已经解决了把二进制文本文件转成.bin文件的问题,并且和老师提供的.bin文件diff一致,这多亏了社区的帮助。但现在我遇到了打印每个32位字的问题,当前我的程序输出是这样的:
initialPC: 16384 dataStartAddress: 272 initialStackPointer: 4243586943 Number of data items: 50331648 16777216 33554432 50331648 17826108 10292 50333988 2596 100682001 2957 4244618531 43951 67110945 16796193 67112968 17826108 10292 3523480612 67112109 167772708 201326592
显然哪里出错了,我不想用AI来完成整个程序——我来学校是学编码的,不是写提示词的,所以想自己搞明白问题出在哪,怎么修正。
我目前的C++代码是这样的:
#include <iostream> #include <fstream> #include <stdexcept> using namespace std; int main(int argc, char* argv[]) { // input error check the proper amount of command arguments if (argc != 3) { cerr << "Usage: " << argv[0] << " input.bin output.txt\n"; //cerr is used for unbuffered error messages return 1; } // open input and output streams, check they open properly ifstream in; in.open(argv[1], ios::binary);//reading in binary mode if (!in.is_open()) throw runtime_error("Error opening input file"); ofstream out; out.open(argv[2]); if (!out.is_open()) throw runtime_error("Error opening output file"); uint word = 0; int count = 0; while (in.read(reinterpret_cast<char*>(&word), 4)) { //read 32 bits (4 bytes) at a time switch (count) { case 0: out << "initialPC: " << word << endl; break; case 1: out << "dataStartAddress: " << word << endl; break; case 2: out << "initialStackPointer: " << word << endl; break; case 3: out << "Number of data items: " << word << endl; break; default: out << word << endl; break; } count++; } //close streams in.close(); out.close(); return 0; }
我用VS Code编写,g++编译,WSL环境运行。我查了一些文件读写的资料,但没说读取后怎么处理数据。
已解决的问题
我发现是字节序的问题,在循环的switch之前加上这行代码后,十进制数值就正确了:
word = __builtin_bswap32(word);
现在我的输出变成了这样:
initialPC: 4194304 dataStartAddress: 268500992 initialStackPointer: 2147479548 Number of data items: 3 1 2 3 1006702593 875036672 604569603 604635136 289996806 2366308352 599654396 2947219456 554172420 558497793 135266308 1006702593 875036672 604767442 2903244804 604110858 12
接下来只需要处理地址递增(数据项从dataStartAddress开始每次加4,指令从initialPC开始每次加4),这部分应该不难。
当前待解决的问题
我现在的疑问是:如何把这些十进制整数转回32位的二进制字符串,输出到文件里? 听说可以用bitset类?暂时先不用考虑汇编解码的部分,先搞定二进制字符串的输出。
备注:内容来源于stack exchange,提问作者Phoenix




