那里有什么好的 68k 汇编程序员吗?我正在为摩托罗拉 68040 使用商业 Green Hills 编译器,我从代码中看到了一些非常奇怪的行为。有时,代码会进行 if/else 比较,并选择错误的分支。例如:
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
代码有时会d!?我发现无论何时发生此错误,总会有一个特定的 ISR 中断比较。我查看了为 ISR 生成的程序集,发现了一些对我来说没有意义的东西。首先,看起来浮点状态寄存器 FPSR、FPCR 和 FPIAR 没有保存在 ISR 中。这可以解释为什么 if/elses 选择了错误的分支。FPSR 寄存器用于确定比较的结果,如果该寄存器在 ISR 中被覆盖,则分支可能会采用错误的路径。以下是编译器生成的入口和出口程序集:
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)
; isr code ...
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
我查看了 Programmer's Reference Manual 并且找不到任何暗示 FSAVE 或 FMOVEM 保存 FP 状态寄存器的内容。实际上,我看到一条评论表明它没有,“FSAVE 不保存浮点单元的程序员模型寄存器;它只保存机器的用户不可见部分。” 所以我添加了一些我自己的程序集来保存 ISR 开始时的寄存器,并在最后恢复它们,这极大地提高了性能,但我仍然看到一些问题。以下是我所做的补充;备份变量在 C 代码中键入为 unsigned long:
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
我很难相信编译器实际上存在错误,因为没有保存寄存器。所以我开始查看 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/等方面有丰富的经验,但我远非汇编专家。
任何想法表示赞赏!