OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6709|回复: 18

为什么stm32主函数不能返回return 0

[复制链接]

52

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
997
金钱
997
注册时间
2017-8-19
在线时间
160 小时
发表于 2022-7-17 15:57:19 | 显示全部楼层 |阅读模式
1金钱
实在理解不了为什么主函数return 0会产生奇怪的现象!

int main(void)
{
  //此处省略其他代码,没有while(1)
    return 0;
}

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
                IMPORT  SystemInit
                LDR     R0, =SystemInit
                BLX     R0               
                LDR     R0, =__main
                BX      R0
                ENDP

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

52

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
997
金钱
997
注册时间
2017-8-19
在线时间
160 小时
 楼主| 发表于 2022-7-17 15:57:53 | 显示全部楼层
我体验了一把只要main函数运行到return 0位置,程序都会出现问题,是什么原因?
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8464
金钱
8464
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-7-17 17:55:31 | 显示全部楼层
那return之后该干嘛呀?运行未知代码?
专治疑难杂症
回复

使用道具 举报

3

主题

821

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3359
金钱
3359
注册时间
2011-11-10
在线时间
207 小时
发表于 2022-7-17 17:57:25 | 显示全部楼层
return 就代表程序运行结束了。单片机歇着了,你还想要什么现象?
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-17 18:13:37 | 显示全部楼层
本帖最后由 candylife9 于 2022-7-17 18:20 编辑

main返回了之后,就回到汇编的Reset_Handler里面了呀,然后Reset_Handler也紧跟着结束。这个时候PC的值就是无效的了,会触发未定义指令异常,然后就会在异常里面执行 B .,相当于while(1) {},出不来了,但是仍然可以响应复位中断,希望选为最佳答案哦。
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-17 18:21:08 | 显示全部楼层
LcwSwust 发表于 2022-7-17 17:55
那return之后该干嘛呀?运行未知代码?

main返回了之后,就回到汇编的Reset_Handler里面了呀,然后Reset_Handler也紧跟着结束。这个时候PC的值就是无效的了,会触发未定义指令异常,然后就会在异常里面执行 B .,相当于while(1) {},出不来了,但是仍然可以响应复位中断,希望选为最佳答案哦。
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8464
金钱
8464
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-7-17 20:41:05 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-7-18 09:07 编辑
candylife9 发表于 2022-7-17 18:21
main返回了之后,就回到汇编的Reset_Handler里面了呀,然后Reset_Handler也紧跟着结束。这个时候PC的值就 ...

从汇编代码看,调用main之后的下一句是ENDP,不是Reset_Handler,且ENDP似乎不是汇编指令,不会生成机器码,那就要看程序烧写后FLASH的相应位置是啥了,估计是0xFFFFFFFF,不清楚是啥指令,可能也会引起复位。

专治疑难杂症
回复

使用道具 举报

0

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-3-17
在线时间
95 小时
发表于 2022-7-17 21:17:30 | 显示全部楼层
和加不加return 0 没关系,你不加编译器也会给你加这句
MOVS     r0,#0
POP      {r4,pc}
main函数如果返回0,代表程序正常退出
回复

使用道具 举报

0

主题

84

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1360
金钱
1360
注册时间
2021-2-25
在线时间
100 小时
发表于 2022-7-18 09:01:34 | 显示全部楼层
返回之后干什么呢?乱跑了
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-18 11:40:58 | 显示全部楼层
LcwSwust 发表于 2022-7-17 20:41
从汇编代码看,调用main之后的下一句是ENDP,不是Reset_Handler,且ENDP似乎不是汇编指令,不会生成机器码 ...

ENDP不是汇编代码,是汇编指令,表示一个汇编函数结束。也就是Reset_Handler到ENP就结束了。一旦Reset_Handler结束了,整个程序代码就跑完了,但是PC还是会尝试取下一条,假设整个代码的结束位置是0x08001000,那么PC会尝试去取0x08001004的指令,但是这个地址并没有指令,所以它会取到一条无效指令,由此引发未定义指令异常,进入对应中断无限循环,看起来就是死机了。
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-18 11:44:31 | 显示全部楼层
LcwSwust 发表于 2022-7-17 20:41
从汇编代码看,调用main之后的下一句是ENDP,不是Reset_Handler,且ENDP似乎不是汇编指令,不会生成机器码 ...

因为main函数就是在Reset_Handler里面调用的,main函数返回后,会回到Reset_Handler继续执行,直到遇到Reset_Handler的ENDP
回复

使用道具 举报

3

主题

821

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3359
金钱
3359
注册时间
2011-11-10
在线时间
207 小时
发表于 2022-7-18 13:16:42 | 显示全部楼层
candylife9 回复的很到位!
回复

使用道具 举报

9

主题

46

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1131
金钱
1131
注册时间
2016-11-9
在线时间
97 小时
发表于 2022-7-18 13:53:39 | 显示全部楼层
本帖最后由 学习阶段 于 2022-7-18 13:55 编辑
candylife9 发表于 2022-7-18 11:44
因为main函数就是在Reset_Handler里面调用的,main函数返回后,会回到Reset_Handler继续执行,直到遇到Re ...

从main返回后,应该是不能再回到Reset_Handler汇编函数里了,这时程序已经跑飞了。因为这里的指令是BX      R0,并没有在LR中保存返回地址的,应该是回不来了。BLX才能回来的吧。我的理解,欢迎指正。


  最基本的无条件转移指令有两条:
B Label ;转移到 Label 处对应的地址
BX reg ;转移到由寄存器 reg 给出的地址
    呼叫子程序时,需要保存返回地址,正点的指令是:
BL Label ;转移到 Label 处对应的地址,并且把转移前的下条指令地址保存到 LR
BLX reg ;转移到由寄存器 reg 给出的地址,根据 REG 的 LSB 切换处理器状态,;并且把转移前的下条指令地址保存到 LR

回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-18 14:08:55 | 显示全部楼层
学习阶段 发表于 2022-7-18 13:53
从main返回后,应该是不能再回到Reset_Handler汇编函数里了,这时程序已经跑飞了。因为这里的指令是BX    ...

也有可能,因为我们并不十分清楚__main具体做了什么,以及return 0的时候是否有恢复某些上下文,反正肯定是进入了未定义指令异常,跑飞其实也是进入了未定义指令异常。如果十分感兴趣,想搞清楚,可以自己做一些验证。
回复

使用道具 举报

52

主题

247

帖子

0

精华

高级会员

Rank: 4

积分
997
金钱
997
注册时间
2017-8-19
在线时间
160 小时
 楼主| 发表于 2022-7-18 18:40:38 | 显示全部楼层
candylife9 发表于 2022-7-18 14:08
也有可能,因为我们并不十分清楚__main具体做了什么,以及return 0的时候是否有恢复某些上下文,反正肯定 ...

我的现象是程序会重新开始跑!我debug也是,return 0会回到__main这里又重新开始
回复

使用道具 举报

2

主题

48

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
373
金钱
373
注册时间
2018-9-14
在线时间
51 小时
发表于 2022-7-19 10:58:46 | 显示全部楼层
关注
回复

使用道具 举报

13

主题

643

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2432
金钱
2432
注册时间
2019-12-28
在线时间
527 小时
发表于 2022-7-19 13:45:46 | 显示全部楼层
楼上大佬们解释的很详细
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2022-7-19 20:57:39 | 显示全部楼层
bbq 发表于 2022-7-18 18:40
我的现象是程序会重新开始跑!我debug也是,return 0会回到__main这里又重新开始

那就只能理解为编译器在程序跑完的时候,自动又帮你把PC设置为__main了,不让它死机了呗。
回复

使用道具 举报

0

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2016-3-17
在线时间
95 小时
发表于 2022-7-20 11:10:00 | 显示全部楼层
candylife9 发表于 2022-7-19 20:57
那就只能理解为编译器在程序跑完的时候,自动又帮你把PC设置为__main了,不让它死机了呗。

如果正常退出,是不断重复这个过程。
一直没搞明白楼主想说明啥,不加死循环这就是正常流程。
因为需要一个返回值,return 0 这句代码不管写不写编译器会自动加上。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 15:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表