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

Intel块大小无效:如何修改32位Hex文件的8字节起始地址?

问题描述

我编写了将xlsm文件转换为Hex文件的Python代码,该功能目前正常运行。生成包含32位数据的Hex文件后,我需要修改首个数据的地址并自动更新后续地址。此前已实现4字节(0000)地址的修改,但适配8字节(00000000)地址后,Hex文件显示无效。

附上当前代码:

def defineNewAdresse(name_file):
    with open(name_file, "rb") as f:
        content = f.readlines()
        adr_list = list(map(lambda x: x[3:6], content))

    if not adr_list:
        adr_list.append("")

    adr_first = checkHexa()
    adr_list[0] = adr_first
    bin_list = []
    formatted_hexa = []

    for i in range(1, len(adr_list)):
        previous_value = int(adr_list[i - 1], 16)
        current_value = previous_value + 16
        adr_list[i] = hex(current_value)[2:].zfill(8)

    for hex_value in adr_list:
        adr_decimal = int(hex_value, 16)
        adr_binary = bin(adr_decimal)[2:]
        bin_list.append(adr_binary)

    for binary_value in bin_list:
        binary_string = format(int(binary_value, 2), "032b")
        hex_num = hex(int(binary_string, 2))[2:].zfill(4)
        formatted_hexa.append(hex_num.zfill(8))

    for i in range(len(content)):
        if i < len(formatted_hexa):
            line = content[i].decode("utf-8")
            modified_line = line[:3] + formatted_hexa[i] + line[7:]
            content[i] = modified_line.encode("utf-8")

    with open(name_file, "wb") as f:
        f.write(b"".join(content))
    f.close()
问题分析

你的代码存在两个核心问题导致Hex文件无效:

  1. 地址字段的截取与替换位置错误:原代码仅截取3个字符作为地址,替换时仅覆盖4个字符的位置,完全不符合8字节地址的长度要求,直接破坏了Hex文件的结构。
  2. 冗余的进制转换:来回在十六进制、十进制、二进制之间转换,不仅无意义,还可能引入格式错误。
修复方案

以下是修正后的代码,解决了8字节地址适配的核心问题,并优化了逻辑:

def defineNewAdresse(name_file):
    # 读取文件并统一转成字符串格式
    with open(name_file, "rb") as f:
        content = [line.decode("utf-8").strip() for line in f.readlines()]
    
    if not content:
        return
    
    # 提取原有8字节地址(假设地址位于每行第3到第10位,共8个十六进制字符)
    adr_list = [line[3:11] for line in content]
    
    # 获取初始地址并规范化为8位十六进制
    adr_first = checkHexa()
    adr_list[0] = adr_first.zfill(8)
    
    # 计算后续地址:每个地址比前一个大16(遵循原逻辑)
    for i in range(1, len(adr_list)):
        prev_addr = int(adr_list[i-1], 16)
        current_addr = prev_addr + 16
        # 生成8位大写十六进制地址(小写用08x)
        adr_list[i] = f"{current_addr:08X}"
    
    # 替换每行的地址字段
    modified_content = []
    for line, new_addr in zip(content, adr_list):
        # 替换第3到第11位的地址为新的8位地址
        modified_line = line[:3] + new_addr + line[11:]
        modified_content.append(modified_line.encode("utf-8"))
    
    # 写入修改后的文件
    with open(name_file, "wb") as f:
        f.write(b"\n".join(modified_content))

关键修改说明

  • 地址位置修正:改为截取8个字符作为地址(line[3:11]),替换时覆盖对应长度的位置(line[:3] + new_addr + line[11:]),确保Hex文件结构不被破坏。
  • 移除冗余转换:直接对十六进制地址转整数计算,避免无意义的进制转换,逻辑更简洁可靠。
  • 格式规范化:用f"{current_addr:08X}"确保生成的地址是标准8位十六进制格式,符合Hex文件的通用要求。
  • 文件读写优化:统一处理换行符,避免因原文件换行格式不一致导致的问题。

额外注意事项

  1. 确保checkHexa()返回有效的8位十六进制字符串(仅含0-9、A-F/a-f),若输入不足8位,代码会自动补零;若输入超出8位,需额外添加截断或校验逻辑。
  2. 如果是标准Intel Hex文件,32位地址需要通过**扩展线性地址记录(类型04)**实现,而非直接修改每条记录的地址字段。若为自定义Hex格式,需确认地址字段的位置和长度与代码中的截取/替换逻辑一致。
  3. 若Hex文件包含校验和字段,修改地址后必须重新计算校验和,否则文件仍会无效,需在代码中添加校验和重新计算的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:32:10