STM32 ARM汇编向数据区数组写值全零问题求解
STM32 ARM汇编冒泡排序问题修复
你遇到的数组初始值全0、排序不生效是两个核心问题导致的,直接按以下方案修改即可。
问题1:自定义数据段未被正确初始化
你当前代码把数组ARR定义在了名为A的自定义DATA段中,STM32的默认启动文件、链接脚本只会自动处理标准段的内存分配与初始值拷贝:
- 只读代码段默认识别
|.text| - 带初始值的可读写数据段默认识别
|.data| - 零初始化数据段默认识别
|.bss|
自定义命名的段如果没有手动修改链接脚本配置,不会被分配到正确的SRAM地址,也不会把你写的初始值1,3,2,4从Flash拷贝到RAM,读内存自然全为0。
问题2:交换逻辑的内存访问错误
你写的交换代码存在原则性错误:
LDR R1,[R0]; // 执行后R1存的是ARR[i]的数值,不是内存地址 STR R2,[R1]; // 把数值当地址写,属于非法内存访问,根本不会修改原数组 STR R3,[R0];
ARM汇编的STR指令方括号内必须是合法内存地址,你这里把从数组里读出来的数值当成地址写入,要么直接触发HardFault,要么写到了和数组无关的内存区域,排序逻辑完全不生效。
修正后可运行代码
AREA |.text|, CODE, READONLY EXPORT __main __main MOV R5,#3 ; 外层循环次数 = 数组长度-1 LDR R0,=ARR ; 加载数组首地址 __LOOP1 CMP R5,#0 BEQ __done ; 外层循环计数为0,排序完成 MOV R6,R5 ; 每轮内层循环比较次数 = 当前外层剩余计数 LDR R0,=ARR ; 内层循环开始前重置指针到数组首地址 __INNER_LOOP CMP R6,#0 BEQ __OUTER_UPDATE ; 内层循环跑完,更新外层计数 LDR R1,[R0] ; 读取ARR[i] LDR R2,[R0,#4] ; 读取ARR[i+1] CMP R1,R2 BLE __NO_SWAP ; 前值<=后值,顺序正确无需交换 STR R2,[R0] ; 交换两个相邻元素 STR R1,[R0,#4] __NO_SWAP SUBS R6,#1 ADDS R0,#4 ; 指针后移4字节(一个字长度) B __INNER_LOOP __OUTER_UPDATE SUBS R5,#1 B __LOOP1 __done B __done ; 排序完成后死循环,防止程序跑飞 AREA |.data|, DATA, READWRITE ARR DCD 1,3,2,4 END
验证说明
代码烧录后进入调试模式,暂停在__done位置时查看ARR对应的内存地址,可看到数组已被正确排序为1,2,3,4,初始值可以正常读取,不会再出现全0问题。
内容的提问来源于stack exchange,提问作者Wong Chung sze
相关产品推荐
相关产品推荐

