在使用 IAR for RL78 1.30.3 时遇到一个奇怪的问题:
调用一个函数(反转 IO 口电平)时总不能达到预期结果,一通分析也查不出个所以然,最后只能通过反汇编结果分析了一下。向函数传递的是 uint8_t 参数(函数定义 void gpio_toggle(uint8_t port) ),使用的却是 16 位的 AX 寄存器,低 8 位存放在 X 寄存器,但进入函数处理时却是从 A 寄存器中取值的(而不是 X),这就导致参数传递错误了。
还发现,奇怪的是在别的地方调用同样的函数却是正常的!传递参数用的是 8 位的寄存器 A:
搞糊涂了,为什么同样的函数在不同文件中调用的结果是不同的呢?而且后续还发现出问题的那个函数所在文件的其他函数也会有类似的问题。于是疯狂地怀疑这儿怀疑那儿,还怀疑是不是这个低版本的编译器存在 Bug 😅
冷静下来后排查了一下编译时的 Warning:
Warning[w6]: Type conflict for external/entry "gpio_toggle", in module ... against external/entry in module hal_gpio; prototyped function vs K&R function
其实警告信息说的不够直白,实际的情况是调用了没有声明的函数(没有引用头文件或头文件中没有声明函数),所以加上声明 extern void gpio_toggle(uint8_t port); 就正常了。
反思:我没把这条警告信息当回事儿,想当然地认为编译链接不报错就应该是正确地链接了,如果是链接到找不到的函数会报错的。实在是大意了😂 找不到函数你倒是不要给我瞎传参数啊,报错也好啊!不知道更新版本的 IAR 是否存在同样的问题,年轻人真是不讲武德啊 😎
总结:认真对待每一条警告信息,耗子尾汁儿!
后记:还真是令我印象更深刻了,后续又遇到了这个问题。把一个 enum 参数传递给了函数,但进到函数后却不能正确地得到这个参数,忽然想到以前遇到过类似的问题,一查还真是没有引用相关头文件!
|