你问了很多事情,但这可以用一个例子来回答:
我发现,在这些更改之后,可执行文件的大小实际上增加了几百字节。
...帮助我了解原因...
通常,您无法预测较小的数据类型是更好还是更差,下面的一小段代码将证明这一点。
要查看发生了什么,您必须查看编译器生成的汇编代码。AVR 工具链有一个组件可以生成这样的列表,通常是一个 .LSS 文件。我不认为 Arduino 支持这一点。下面的程序集清单是通过 Eclipse 生成的,它默认驱动扩展清单。
这是 LED 闪烁程序的一小部分,可用于证明您的困惑。它有一个在循环中设置给 LED 的亮度值:
boolean fadein = true;
int bright = 0; // we will change this data type int <-> int8_t
void loop() {
// adjust brightness based on current direction
if(fadein) {
bright += 1;
}
else {
bright -= 1;
}
// apply current light level
analogWrite(13,bright);
为了演示,bright变量在 1 字节和 2 字节 int 之间变化,我们比较汇编列表:
比较增量线
以下是具有两种数据类型的增量行的清单:
// int bright - increment line - must load and store 2 bytes
// 18 bytes of code
bright += 1;
18a: 80 91 02 01 lds r24, 0x0102
18e: 90 91 03 01 lds r25, 0x0103
192: 01 96 adiw r24, 0x01 ; 1
194: 90 93 03 01 sts 0x0103, r25
198: 80 93 02 01 sts 0x0102, r24
第一列是代码空间地址,第二列是实际的代码字节,最后一列是汇编人类可读的形式。LDS 是从内存加载,ADIW 是加法,STS 是存回内存
这是较小的数据类型,具有预期的结果:
// int8_t bright - increment line - only load and store 1 byte
// 10 bytes of code
bright += 1;
18a: 80 91 02 01 lds r24, 0x0102
18e: 8f 5f subi r24, 0xFF ; 255
190: 80 93 02 01 sts 0x0102, r24
请注意 SUBI 255 而不是添加 1 的奇怪之处——这是编译器开发人员的技巧。
所以你去吧,较小的数据类型会产生更小的代码,如你所料。你是对的!哦等等,你已经说过你不正确的地方......
比较函数调用
但是函数调用呢?analogWrite() 方法需要一个 int,因此如果需要,编译器将被迫创建一个转换
// int - needs no type conversion, can directly load value
// from addresses 0x0102 and 0x0103 and call
// 16 bytes code
// apply current light level
analogWrite(13,bright);
1b0: 20 91 02 01 lds r18, 0x0102
1b4: 30 91 03 01 lds r19, 0x0103
1b8: 8d e0 ldi r24, 0x0D ; 13
1ba: b9 01 movw r22, r18
1bc: 0e 94 87 02 call 0x50e ; 0x50e <analogWrite>
LDI 正在加载常量,MOVW 正在移动变量以准备调用。
// int8_t - needs a type conversion before call
// 20 bytes code
// apply current light level
analogWrite(13,bright);
1a0: 80 91 02 01 lds r24, 0x0102
1a4: 28 2f mov r18, r24
1a6: 33 27 eor r19, r19
1a8: 27 fd sbrc r18, 7
1aa: 30 95 com r19
1ac: 8d e0 ldi r24, 0x0D ; 13
1ae: b9 01 movw r22, r18
1b0: 0e 94 76 02 call 0x4ec ; 0x4ec <analogWrite>
无需了解类型转换的程序集即可看到效果。较小的数据类型产生了更多的代码。
那么这是什么意思呢?较小的数据类型既减少了代码大小又增加了代码大小。除非您可以在脑海中编译代码,否则您无法通过检查来解决这个问题,您必须尝试一下。