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

STM32指令拆分异常:Python中16/32位指令识别错误求助

解决STM32指令拆分中32位/16位指令误判问题

问题场景

用Python读取STM32的hex文件,转换为大端序二进制字符串后,尝试按每行一条指令拆分写入新文件,但部分32位指令被误识别为16位,导致拆分错误。原处理函数及判断规则如下:

原错误代码

def generate_instructions_file():
    instruction_file = open("./instructions_file.txt", "w")
    with open("./binary_reformatted.txt") as file:
        data = file.read()
        i = 0
        while i < len(data)-15:
            tmp = data[i:i+32]
            if tmp[24:27] == '111' and (tmp[27:29] != '00' or tmp[27:29] == '01' or tmp[27:29] == '10' or tmp[27:29] == '11'):
                b0 = tmp[:8]
                b1 = tmp[8:16]
                b2 = tmp[16:24]
                b3 = tmp[24:]
                newtmp = b3 + b2 + b1 + b0
                instruction_file.write(newtmp + '\n')
                i += 32
            else:
                tmp = data[i:i+16]
                b0 = tmp[:8]
                b1 = tmp[8:]
                newtmp = b1 + b0
                instruction_file.write(newtmp + '\n')
                i += 16

判断规则

  • 大端序下,指令以111开头且后续两位不为00(即11100开头的为16位指令),则为32位指令。

错误分析

  • 判断逻辑的基础错误:原代码先读取32位片段进行判断,但如果当前是16位指令,片段的后16位属于下一条指令,导致用下一条指令的内容来判断当前指令类型,必然误判。
  • 冗余条件:(tmp[27:29] != '00' or tmp[27:29] == '01' or ...)完全冗余,!= '00'已包含后面三种情况。
  • 循环边界错误:i < len(data)-15可能导致末尾不足32位但仍有16位有效指令的情况被截断。

修复方案

正确的逻辑应该是先取当前16位片段转大端,判断是否为32位指令的第一部分,再决定是否读取后续16位组成32位指令。修复后的代码如下:

def generate_instructions_file():
    with open("./instructions_file.txt", "w") as instruction_file, open("./binary_reformatted.txt") as file:
        data = file.read().strip()  # 移除可能的换行、空格
        i = 0
        data_len = len(data)
        while i < data_len:
            # 剩余长度不足16位,停止处理
            if data_len - i < 16:
                break
            
            # 读取当前16位小端片段,转为大端16位
            tmp_16 = data[i:i+16]
            b0_16 = tmp_16[:8]
            b1_16 = tmp_16[8:]
            big_endian_16 = b1_16 + b0_16
            
            # 判断是否为32位指令:大端16位前3位是111,且前5位不是11100
            if big_endian_16[:3] == '111' and big_endian_16[:5] != '11100':
                # 剩余长度不足32位,无法组成32位指令,按16位处理(容错)
                if data_len - i < 32:
                    instruction_file.write(big_endian_16 + '\n')
                    i += 16
                    continue
                # 读取完整32位小端片段,转为大端32位
                tmp_32 = data[i:i+32]
                b0 = tmp_32[:8]
                b1 = tmp_32[8:16]
                b2 = tmp_32[16:24]
                b3 = tmp_32[24:]
                big_endian_32 = b3 + b2 + b1 + b0
                instruction_file.write(big_endian_32 + '\n')
                i += 32
            else:
                # 16位指令
                instruction_file.write(big_endian_16 + '\n')
                i += 16

修复要点

  • 先判断16位片段:基于当前16位的大端内容判断指令类型,避免引用下一条指令的内容。
  • 添加长度校验:处理前检查剩余长度,避免索引越界和无效指令。
  • 简化判断条件:直接用大端16位的前3位和前5位做判断,符合ARM Thumb-2指令的规则。
  • 文件操作优化:使用with语句同时管理两个文件,确保资源正确释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:10:39