gpt4 book ai didi

compiler-construction - 68040 If Else 走错分支

转载 作者:行者123 更新时间:2023-12-04 08:37:24 25 4
gpt4 key购买 nike

有没有好的 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/else 选择错误的分支。 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

我查看了程序员引用手册,但找不到任何表明 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/等方面有丰富的经验,但我远不是汇编专家。

任何想法表示赞赏!

最佳答案

为了将来引用,问题确实与编译器没有保存浮点状态寄存器的值有关。我联系了 Green Hills,据他们说这不是错误,保存寄存器的值是程序员的责任。这对我来说很奇怪,因为编译器保存了所有其他内部寄存器,包括 FPU 的内部状态,为什么停止状态寄存器?

简而言之,保存进入的 FPSR 和 FPIAR 的值,当离开 ISR 时将纠正问题。以下应该可以解决问题:

void isr(void)
{
// variable declarations ...

__asm(" FMOVE %FPIAR,-(%SP)");
__asm(" FMOVE %FPSR,-(%SP)");

// some code ...


__asm(" FMOVE (%SP)+,%FPSR");
__asm(" FMOVE (%SP)+,%FPIAR");
}

关于compiler-construction - 68040 If Else 走错分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8117788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com