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

求助:如何将整数数组转为单个十六进制数?MBR的LBA地址转换异常

磁盘MBR LBA地址转换问题解决

问题根源分析

你当前的转换代码存在多个致命问题:

  • 数组越界访问:循环i < 4时,当i=3,nums[i+1]会访问nums[4],超出了数组的合法索引范围(0-3),读取到的是内存中的随机垃圾数据,这就是全0数组却得到4e9052eb这类乱码的核心原因。
  • 位移计算错误:8*i+1的位移逻辑完全不符合小端字节序的拼接规则,MBR中存储的LBA是小端格式(低字节在前),正确的位移应该是每个字节对应左移8*i位(i为数组索引)。
  • 变量未初始化:finalNum没有初始化为0,初始值是内存中的随机值,后续位运算会基于这个随机值计算,结果必然错误。
  • 拼接逻辑错误:每次循环用nums[i]和nums[i+1]组合赋值,这不是4字节拼接成32位整数的正确方式。

修正后的代码实现

第一步:优化MBR数据读取(可选,但更可靠)

原读取代码逐个判断索引的方式容易出错,直接从MBR的486偏移量开始读取连续4个字节即可:

uint8_t LBAAddr[4];
// 从MBR的486偏移处读取起始LBA的4个字节(小端存储)
for(int i = 0; i < 4; i++) {
    LBAAddr[i] = b[486 + i];
    fprintf(stdout, "%02x ", LBAAddr[i]);
}

第二步:正确转换为uint32_t整数

基于小端字节序的规则,将4字节数组拼接为32位无符号整数:

uint32_t finalNum = 0;
// 小端转主机字节序:数组索引0是最低位字节
finalNum |= (uint32_t)LBAAddr[0] << 0;
finalNum |= (uint32_t)LBAAddr[1] << 8;
finalNum |= (uint32_t)LBAAddr[2] << 16;
finalNum |= (uint32_t)LBAAddr[3] << 24;

// 或者用循环实现
uint32_t finalNum = 0;
for(int i = 0; i < 4; i++) {
    finalNum |= (uint32_t)LBAAddr[i] << (8 * i);
}

printf("转换后的LBA地址:%u(十六进制:%08x)\n", finalNum, finalNum);

额外说明

MBR分区表中,每个分区项的起始LBA存储在偏移486-489的4个字节中,采用小端字节序存储,即第一个字节是LBA值的最低8位,最后一个字节是最高8位,转换时必须遵循这个规则才能得到正确的数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:13:30