近日使用汇编写电机变频器的算法,uCOS-II写的汇编函数。一不留神忘记在汇编函数里把要使用的寄存器压堆,导致电机经常停转。由于程序巨大,调了半天才找出这个小BUG。 网上有人说C调用子函数前,编译器会自动加入PUSH指令,把子函数要使用的寄存器压堆,返回后又自动加入POP指令出栈。如果子函数是C语言写的,那是正确的,但如果是汇编写的,那就只对一半!如果编译不优化,那么编译器把汇编函数当成C函数,会加入压栈和出堆指令;但如果选择优化,那么编译器有可能把汇编函数的代码,直接复制到调用它的地方,不按调用函数的流程,更不会加入压栈和出堆指令,如果汇编函数没有自我压栈,那程序会跑飞!我的变频器算法就是这样。
另外,uCOS官方的移植模板触法任务调度的函数是这样写的: OSCtxSw LDR R4, =NVIC_INT_CTRL ; trigger the PendSV LDR R5, =NVIC_PENDSVSET STR R5, [R4] BX LR 如果选择优化编译,这段代码就有可能使单片机跑飞!正确的写法应该是(不管编译器会不会加入压栈和出堆指令): OSCtxSw PUSH {R4, R5} LDR R4, =NVIC_INT_CTRL ; trigger the PendSV LDR R5, =NVIC_PENDSVSET STR R5, [R4] POP {R4, R5} BX LR
(zlgarm_zsg) |