为何CodeVision会生成存储函数参数至RAM的冗余汇编代码?
为什么CodeVision会生成多余的参数存/取RAM指令?
这确实是个挺让人困惑的细节——明明你的函数只需要把寄存器里的value直接写到数组里,CodeVision却多做了一次把参数存到栈、再读回来的操作,平白浪费了4个周期,完全没必要对吧?
结合AVR编译器的常见行为,这里可能有几个原因:
通用函数调用框架的“惯性”处理:CodeVision大概率是基于一套标准化的函数调用模板生成代码的。不管当前函数会不会修改参数、或者有没有后续复用参数的需求,它都会先把寄存器里的参数存到栈帧的参数区域(也就是汇编里Y指针指向的位置)。这种框架化的处理方式对编译器来说开发和维护成本更低,不用为每个小函数单独做特殊判断,只是牺牲了一点点极端场景下的性能。
优化等级未拉满:如果你的编译器没开启最高级别的优化,这类冗余的栈操作很可能会被保留。去看看CodeVision的优化设置——比如有没有类似
-O2的编译选项,或者图形界面里的“激进优化”“消除冗余内存操作”这类选项,开启后编译器应该能识别到这两步操作完全多余,直接生成更精简的代码。调试模式的遗留行为:如果你是在调试模式下编译的,编译器会优先保证调试的便利性,故意把参数存到栈里,方便你在调试时查看函数参数的值。这种情况下切换到Release模式,冗余指令大概率会消失。
再看你的具体代码:参数value一开始就存在R26里,直接执行STD Z+0,R26就能完成赋值,中间的ST -Y,R26和LD R26,Y完全是画蛇添足——上面的几个原因里,前两个的可能性最高。
内容的提问来源于stack exchange,提问作者NikkyD
相关产品推荐
相关产品推荐

