Compiler construction 68040采用了错误的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不会保存浮点单元的程序员模型寄存器;它只保存

有没有优秀的68k汇编程序员??我正在为摩托罗拉68040使用一个商业的Green Hills编译器,我从代码中看到一些非常奇怪的行为。有时,代码会进行if/else比较,并采用错误的分支。例如:

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");
}