9 c microcontroller assembly msp430 mspgcc
在msgpcc(GSP for MSP430微控制器)手册中,作者写道:
如果要在函数中使用小整数,请使用int而不是char或unsigned char.生成的代码将更有效,并且在大多数情况下,实际上不会浪费存储.
为什么int
效率更高?
UPD.为什么(u)int_fast8_t
在mspgcc中定义(unsigned) char
,而不是(unsigned) int
.据我所知,(u)int_fast*_t
应该定义为具有足够大小的最有效类型.
TI已针对其Tiva-C(正式Stellaris)MCU发布了有关该主题的应用笔记.
在"简介"部分中,表格提供了影响性能和大小的因素列表.一个因素标签可变大小的规定," 使用非最佳小变量可能意味着额外的指令签名或unsign扩展...... ".
此外,在"变量大小"一节中,它指出:
"当局部变量小于寄存器大小时,通常需要额外的代码.在Stellaris部分,这意味着大小为byte和halfword(分别为char和short int)的局部变量需要额外的代码. 8位或16位微控制器可能已将本地转换为较小的尺寸(以避免太大的问题),这意味着此类代码将运行得更慢并占用更多的代码空间."
请参阅:http://www.ti.com/lit/an/spma014/spma014.pdf
以下内容由编译器处理,但仍与手头的问题有关:
MSP430是一款16位微处理器.char只有8位,需要打包以确保所有单词都对齐.例如,3个字符在内存中无法正确对齐.相反,使用16位的整数并始终对齐.
当您使用16的倍数(例如16和32)的可变大小时,您还可以更有效地利用内存.您最终不会使用填充来对齐内存.
一般来说,不一定特定于该处理器,它与符号扩展和屏蔽有关,需要额外的指令才能忠实地实现 C 源代码。16 位、32 位或 64 位处理器中的带符号 8 位值可能涉及额外的符号扩展指令。32 位处理器上的 8 位添加可能涉及到 0xFF 等的额外指令。
你应该做一些简单的实验,这需要几次迭代,但我很快就发现了一些显示出差异的东西。
unsigned int fun ( unsigned int a, unsigned int b )
{
return(a+b)<<3;
}
unsigned char bfun ( unsigned char a, unsigned char b )
{
return(a+b)<<3;
}
int sfun ( int a, int b )
{
return(a+b)<<3;
}
char sbfun ( char a, char b )
{
return(a+b)<<3;
}
Run Code Online (Sandbox Code Playgroud)
产生
00000000 <fun>:
0: 0f 5e add r14, r15
2: 0f 5f rla r15
4: 0f 5f rla r15
6: 0f 5f rla r15
8: 30 41 ret
0000000a <bfun>:
a: 4f 5e add.b r14, r15
c: 4f 5f rla.b r15
e: 4f 5f rla.b r15
10: 4f 5f rla.b r15
12: 30 41 ret
00000014 <sfun>:
14: 0f 5e add r14, r15
16: 0f 5f rla r15
18: 0f 5f rla r15
1a: 0f 5f rla r15
1c: 30 41 ret
0000001e <sbfun>:
1e: 8f 11 sxt r15
20: 8e 11 sxt r14
22: 0f 5e add r14, r15
24: 0f 5f rla r15
26: 0f 5f rla r15
28: 0f 5f rla r15
2a: 4f 4f mov.b r15, r15
2c: 30 41 ret
Run Code Online (Sandbox Code Playgroud)
msp430 具有字和字节版本的指令,因此简单的加法或减法不必执行您在使用小于寄存器大小的变量时所期望的剪切或符号扩展。作为一名程序员,我们可能知道我们只会向 sbfun 提供一些非常小的数字,但编译器不会,并且必须忠实地实现我们编写的代码,在 sfun 和 sbfun 之间生成更多代码。使用不同的编译器和处理器进行这些实验以查看其实际效果并不难,唯一的技巧是创建处理器没有简单指令来解决的代码。
另一个例子
unsigned int fun ( unsigned int a, unsigned int b )
{
return(a+b)>>1;
}
unsigned char bfun ( unsigned char a, unsigned char b )
{
return(a+b)>>1;
}
Run Code Online (Sandbox Code Playgroud)
产生
00000000 <fun>:
0: 0f 5e add r14, r15
2: 12 c3 clrc
4: 0f 10 rrc r15
6: 30 41 ret
00000008 <bfun>:
8: 4f 4f mov.b r15, r15
a: 4e 4e mov.b r14, r14
c: 0f 5e add r14, r15
e: 0f 11 rra r15
10: 4f 4f mov.b r15, r15
12: 30 41 ret
Run Code Online (Sandbox Code Playgroud)