You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动