gpt4 book ai didi

c - 为什么 a*b/c 而不是 a*(b/c) 在 AVR 上提供 3 倍大的程序大小?

转载 作者:行者123 更新时间:2023-12-03 20:05:55 24 4
gpt4 key购买 nike

最近我试图将我的代码打包到带有 1kB 闪存的小型 ATTiny13 中。在优化过程中,我发现了一些奇怪的东西。让我们以示例代码为例:

#include <avr/interrupt.h>

int main() {
TCNT0 = TCNT0 * F_CPU / 58000;
}

它当然没有意义,但有趣的是输出大小 - 它产生 248 字节 .

代码快速说明: F_CPU是由 -DF_CPU=... 定义的常量切换为 avr-gcc , TCNT0是 8 位寄存器(在 ATTiny13 上)。在实际程序中,我将方程结果分配给 uint16_t,但仍观察到相同的行为。

如果表达式的一部分被括在括号中:
TCNT0 = TCNT0 * (F_CPU / 58000);

输出文件大小为 70 字节 .巨大的差异,但这些操作的结果是相同的(对吧?)。

我查看了生成的汇编代码,尽管我不太了解 ASM,但我看到无括号版本添加了一些标签,例如:
00000078 <__divmodsi4>:
78: 05 2e mov r0, r21
7a: 97 fb bst r25, 7
7c: 16 f4 brtc .+4 ; 0x82 <__divmodsi4+0xa>
7e: 00 94 com r0
80: 0f d0 rcall .+30 ; 0xa0 <__negsi2>
82: 57 fd sbrc r21, 7
84: 05 d0 rcall .+10 ; 0x90 <__divmodsi4_neg2>
86: 14 d0 rcall .+40 ; 0xb0 <__udivmodsi4>
88: 07 fc sbrc r0, 7
8a: 02 d0 rcall .+4 ; 0x90 <__divmodsi4_neg2>
8c: 46 f4 brtc .+16 ; 0x9e <__divmodsi4_exit>
8e: 08 c0 rjmp .+16 ; 0xa0 <__negsi2>

以及更多。我只学习了一段时间的 x86 汇编程序,但据我所知,除法有简单的助记符。为什么 avr-gcc在第一个示例中添加了这么多代码?

另一个问题是,如果两个数字在编译时已知,为什么编译器不内联方程的右边部分。

最佳答案

我们有这个:

x = x * 1200000 / 58000

请注意 1200000/58000 = 20.69...不是整数,所以这必须计算为首先乘以然后地板除法。您的架构没有针对此数据类型的原生整数除法,因此必须对其进行模拟,从而产生大量代码。

然而这个:
x = x * (1200000 / 58000)

我们发现 1200000 / 58000 = 20 , 由于C使用地板师 ,所以这段代码被简化为:
x = x * 20

关于c - 为什么 a*b/c 而不是 a*(b/c) 在 AVR 上提供 3 倍大的程序大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62302796/

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