【问题标题】:SDCC generates unnecessary division by zeroSDCC 产生不必要的除以零
【发布时间】:2021-07-23 11:36:21
【问题描述】:

我正在使用 SDCC 为 STM8 微控制器进行编译。编译以下文件会导致看似不必要的 div 指令——这在 STM8 上非常慢。

char a[1];
char b;

void foo() __interrupt(1) {
    char c = a[0];
    b = c >> 0;
}

void main() {
}

使用sdcc -mstm8 file.c 编译会产生以下程序集:

_foo:
    clr a
    div x, a
    ld  a, _a+0
    ld  _b+0, a
    iret

该功能似乎按预期工作,但我不明白为什么需要前两条指令。

【问题讨论】:

  • 你编译时是否开启了优化?请出示minimal reproducible example。一个破碎的 if 块没有意义
  • manual 表示如果分母为零,则操作数寄存器不受影响。 div 是可中断的。所以这是一个零被推动,而不是一个余数。总而言之,这看起来像是故意拖延。我想知道这是否与中断协议有关。也许是时候锁存数据寄存器之类的了。
  • 您有什么问题我们可以回答? -- 顺便说一句,SDCC 项目有一个友好的用户邮件列表。您可能想在那里询问原因。
  • iret 指令在哪里?这看起来不像 ISR 的正确/完整反汇编。如果您放弃过时的 C 样式并将函数正确编写为 void updateDisplay(void) __interrupt(23),这有什么不同吗?
  • @phuclv 我用尽可能少的代码重写了这个问题,可以看到 div 指令。我的 SDCC 版本是 4.1.0。

标签: c compilation divide-by-zero sdcc stm8


【解决方案1】:

看起来这是编译器某处的错误,因为如果将 b = c >> 0 更改为 b = c << 0b = c + 0b = a[0]... 则不会发生此类事情。在优化和未优化的代码上都可以观察到这种行为。但是,如果您针对大小(--opt-code-size)进行优化,那么只有div 存在,clr 指令不会发出。你可能想report that to the developers

Demo on Compiler Explorer

【讨论】:

猜你喜欢
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
相关资源
最近更新 更多