点击上方 “ 畅学电子 ” 一键关注,轻松学习电子知识
最近有个新手问我,遇到51编译一堆报警 uncall segment。表面上是函数没有调用,但本质上还是51的静态编译所致。我觉得有必要以吐槽的方式好好为菜鸟“出气”一下,遂有此文。 背景知识理解: 这两个背景知识,就是51万恶的根源.... 1. 静态栈编译方式: 连局部变量的地址都是固定的哦。它不是栈压出来的,是编译器他老人家静态分析整个系统树,计算调用深度,运筹帷幄,一次分配给你的。 所以,一旦有游离在外的uncall,不管是函数还是变量,他老人家就紧张兮兮的,非得给你一个黄牌。遇到函数指针那种严重烧脑的动态调用关系,他老人家就崩溃了。 2. C51的四个bank寄存器组。每个using 数字对应一个个bank。 效率靠它,bug也靠它。 C51的吐槽点: 1.waning: uncall segment 不仅是未调用的函数会报Waning,没用到的code也报。 在M3这里,只有static声明的东西没有使用,才会报警。 解决方式: void uncall_func(void) { uint8_t f = 0; if (f) /* 许多编译器都默许这样的做法,不能吐槽C51暮气昏庸 */ { As you know } } 2. using搞不清 . 不是每个中断要一个单独using,只要优先级不嵌套,用同一个也可以, . 一处using处处using, 指定using的函数其所调用的所有子子孙孙,都要using或者NOAREG. . 如果要提高某个效率,可单独分配一个bank给它,就是单独的using数字。 3. 函数指针:不做死就不会死。 51的函数指针,形同鸡肋,想用它,就要去了解reentry,重入,搞个动态栈,然后就是做死的节奏。 我唯一一次用到,是这样写的 staticconstFUNC_TYPE func =******_function_name; 告诉你,就这样子,编译器都紧张得要死,老版本也分析不了全局树,还会出错。 4.51的存储类别 xdata/data/code/sbit算是菜鸟能够了解的,加上idata/pdata连我也要爆粗口了 然而其本质上是bus总线访问数据的区别,就是MOV等汇编指令的不同变体。 这方面,还是请个大牛来讲解吧,我目前的理解深度,还没法一气呵成。吐槽无力了 5.大端结构 包括许多老工程师,把51的程序移植到M3后,才发现噩梦其实才刚刚开始。 实际上,许多网络协议,包括自定义的,默认是大端的,我想它的初衷是方便人眼抓包阅读。 但作为一个菜鸟,切不可贪图51的大端便利,写出大小端移植性不好的代码。 不去了解大小端,心里没有度,出来混的,总有还的一天。 6.应该还有很多,但我真心忘却了。 菜鸟大虾们,来尽情吐槽吧... 诸位牛人也会有很强的解答**。 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|