Python解析STM32十六进制文件:16/32位指令拆分异常求助
STM32 SREC文件指令拆分错误:32位指令被误判为16位
你的问题出在Thumb-2指令的类型判断逻辑错误:当前代码基于32位二进制串的高字节片段判断指令长度,但正确的规则是通过第一个16位半字的高5位来识别32位指令。
原代码的核心问题
原代码中判断32位指令的条件:
if tmp[24:27] == '111' and tmp[27:29] != '00':
这个条件检查的是未反转字节的32位串第24-29位(对应内存中最高地址字节的前5位),但Thumb-2 32位指令的标识是低地址处的16位半字(前缀)的高5位为11101/11110/11111。你的判断逻辑完全偏离了指令集规则,导致32位指令的后半部分被误判为独立的16位指令。
修正后的代码
def function(filepath): # 读取SREC文件,自动管理文件资源 with open(filepath, 'r') as stm_file: stm_lines = stm_file.readlines() data_hex = "" for line in stm_lines: # 跳过结束行S7 if line.startswith('S7'): continue # 提取每行的数据段:跳过前12字符(S3+长度+地址),跳过最后3字符(校验码+换行) data_hex += line[12:-3] # 十六进制转二进制字符串,每个字符转4位补零的二进制 data_binary = ''.join(bin(int(c, 16))[2:].zfill(4) for c in data_hex) # 写入指令文件 with open("./instructions_file.txt", "w") as instr_file: i = 0 total_bits = len(data_binary) # 循环处理,保证至少有16位数据可读取 while i <= total_bits - 16: # 读取当前16位(内存中低地址的半字) tmp_16 = data_binary[i:i+16] # 反转字节得到Thumb指令的正确顺序(小端存储转指令二进制) instr_16 = tmp_16[8:] + tmp_16[:8] # 获取指令高5位,判断是否为32位指令前缀 instr_prefix = instr_16[:5] if instr_prefix in ('11101', '11110', '11111'): # 32位指令:读取后续16位,组合成完整32位指令 if i + 32 > total_bits: break # 数据不完整时终止,正常SREC不会出现此情况 tmp_32 = data_binary[i:i+32] # 反转四个字节得到32位指令的正确顺序 instr_32 = tmp_32[24:] + tmp_32[16:24] + tmp_32[8:16] + tmp_32[:8] instr_file.write(instr_32 + '\n') i += 32 else: # 16位指令直接写入 instr_file.write(instr_16 + '\n') i += 16 if __name__ == '__main__': function("./clignoter_led.srec")
关键改进说明
- 正确的指令识别:提取当前16位指令的高5位,严格匹配Thumb-2 32位指令的前缀规则
- 资源安全:使用
with语句处理文件,避免手动关闭文件导致的资源泄漏 - 鲁棒性提升:跳过S7结束行,增加数据完整性检查
- 代码简化:用生成器表达式替代循环拼接二进制字符串,更高效简洁
验证逻辑
修正后的代码会按以下流程处理:
- 读取每个16位半字,反转字节得到正确的16位指令顺序
- 检查指令高5位:
- 若为
11101/11110/11111,则读取后续16位,反转四个字节后写入完整32位指令 - 否则直接写入16位指令
- 若为
这样就能彻底解决32位指令被误拆分的问题,完全符合STM32 Thumb-2指令集的存储规则。
内容的提问来源于stack exchange,提问作者Hugo MERLE
相关产品推荐
相关产品推荐

