Compiler construction 68040采用了错误的If-Else分支
有没有优秀的68k汇编程序员??我正在为摩托罗拉68040使用一个商业的Green Hills编译器,我从代码中看到一些非常奇怪的行为。有时,代码会进行if/else比较,并采用错误的分支。例如:Compiler construction 68040采用了错误的If-Else分支,compiler-construction,assembly,68000,isr,Compiler Construction,Assembly,68000,Isr,有没有优秀的68k汇编程序员??我正在为摩托罗拉68040使用一个商业的Green Hills编译器,我从代码中看到一些非常奇怪的行为。有时,代码会进行if/else比较,并采用错误的分支。例如: float a = 1, b = 2; if (a < b) do c; else do d; 我查阅了程序员参考手册,没有找到任何建议FSAVE或FMOVEM保存FP状态寄存器的内容。事实上,我看到一条评论表明它没有“FSAVE不会保存浮点单元的程序员模型寄存器;它只保存
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
我查阅了程序员参考手册,没有找到任何建议FSAVE或FMOVEM保存FP状态寄存器的内容。事实上,我看到一条评论表明它没有“FSAVE不会保存浮点单元的程序员模型寄存器;它只保存机器中用户看不见的部分。”因此我添加了一些我自己的程序集,在ISR开始时保存寄存器,并在结束时恢复它们,这大大提高了性能,但我仍然看到一些问题。以下是我所作的补充;在C代码中,备份变量的类型为无符号长:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
FMOVE %FPIAR,fpiar_backup
FMOVE %FPSR,fpsr_backup
FMOVE %FPCR,fpcr_backup
; isr code ...
FMOVE fpiar_backup,%FPIAR
FMOVE fpsr_backup,%FPSR
FMOVE fpcr_backup,%FPCR
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
我很难相信编译器因为没有保存寄存器而真的有一个bug。所以我开始查看FPx和Dx的值,看看它们是否恢复到了正确的值,但看起来它们不是。然而,我并不是100%地认为我的修改没有污染汇编代码。下面是我为保存寄存器而添加的代码;调试变量的类型为无符号长:
isr_function:
FMOVE %FP0,debug3
FMOVE %FP1,debug5
FMOVE %FP2,debug7
FMOVE %FP3,debug9
FMOVE %FP4,debug11
FMOVE %FP5,debug13
FMOVE %FP6,debug15
FMOVE %FP7,debug17
FMOVE %FPCR,debug19
FMOVE %FPIAR,debug23
FMOVE %FPSR,debug25
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FMOVE %FP0,debug4
FMOVE %FP1,debug6
FMOVE %FP2,debug8
FMOVE %FP3,debug10
FMOVE %FP4,debug12
FMOVE %FP5,debug14
FMOVE %FP6,debug16
FMOVE %FP7,debug18
FMOVE %FPCR,debug20
FMOVE %FPIAR,debug24
FMOVE %FPSR,debug26
FRESTORE (%SP)+
RTE
简言之,我的问题是
1) 生成的程序集是否存在不保存FPSR、FPCR和FPIAR寄存器的问题,以及
2) 当我进入和退出ISR时,是否正确保存了寄存器的值
如果我有另一个编译器来比较,那就太好了。不幸的是,我无法将调试器附加到代码。我在C/C++/C#/Java/Python/PHP/等方面有丰富的经验,但我远非汇编专家
任何想法都很感激 从68020时代起,我就没有做过68K编程,但我会尝试深入到相关的灰质和/或web资源:-) 回答您的具体问题: 生成的程序集是否存在不保存FPSR、FPCR和FPIAR寄存器的问题 我会说是的,但前提是ISR中有影响他们的东西。虽然这似乎不太可能(ISR应该很快,所以我不希望他们在处理浮点数据),但prudence似乎建议使用一个例程保存所有内容,以防代码可能会更改它 话虽如此,我不确定您是如何编译ISR的(甚至不知道它是否是您的代码)。可能需要一个特殊的标志来让编译器生成更多代码以保存其他内容 当我进入和退出ISR时,是否正确保存了寄存器的值 同样,这要视情况而定。看起来还可以,但我会有点担心使用特定的内存位置,如
fpiar\u backup
或debug26
,除非您非常确定ISR本身不容易再次中断
如果中断在ISR处理期间被禁用,那么您可能没事
此外,这取决于ISR服务的内容。文档似乎表明,任何为浮点问题提供服务的ISR都应该首先执行fsave
如果您转储了那些
debugX
位置的值,以便查看ISR入口和出口之间的不同值,这将非常有用。确保尺寸合适。注意,在ISR的中间没有看到它们,在这里它们几乎肯定是不同的。 < P>对于将来的引用,这个问题确实与编译器不保存浮点状态寄存器的值有关。我联系了Green Hills,据他们说,这不是一个bug,保存寄存器的值是程序员的责任。这对我来说很奇怪,因为编译器保存了所有其他内部寄存器,包括FPU的内部状态,为什么停止使用状态寄存器
简言之,保存进入和离开ISR时的FPSR和FPIAR值将纠正问题。下面应该可以做到这一点:
void isr(void)
{
// variable declarations ...
__asm(" FMOVE %FPIAR,-(%SP)");
__asm(" FMOVE %FPSR,-(%SP)");
// some code ...
__asm(" FMOVE (%SP)+,%FPSR");
__asm(" FMOVE (%SP)+,%FPIAR");
}
谢谢你的反馈!我并不真正理解使用特定内存位置的重要性。“我会有点担心使用特定的内存位置,如fpiar_backup或debug26,除非您非常确定ISR本身不会再发生中断。”这些变量只在该ISR中写入。我看不出这会有什么负面影响。我不确定中断优先级,但另一个中断可能会干扰。@user1045004:我担心的是,如果在ISR运行时发生另一个中断,它可能会覆盖这些值。这只是一个问题,如果相同的代码运行如此,如果另一个中断是不同的,那就可以了。这是正确的,如果您编写一个中断服务例程,您确实需要注意自己正确地执行它。这意味着保存机器状态,包括状态寄存器。通常编译器无法做到这一点-大多数语言缺少中断所需的语言构造,但有些语言具有函数属性或扩展。我很困惑,仅仅添加浮点或双关键字就可能以如此微妙的方式受到惩罚。我与Green Hills代表进行了更多的交谈,我认为他看到了我的观点,他提出了为本例添加文档的请求,并在编译器中添加一个标志,以自动保存FP寄存器。
void isr(void)
{
// variable declarations ...
__asm(" FMOVE %FPIAR,-(%SP)");
__asm(" FMOVE %FPSR,-(%SP)");
// some code ...
__asm(" FMOVE (%SP)+,%FPSR");
__asm(" FMOVE (%SP)+,%FPIAR");
}