资料介绍
14.8 变量类型
ARM C编译器支持基本的数据类型:char、short、int、long long、float和double。表14.2说明了armcc对C语言所使用的数据类型的映射。
表14.2 C编译器数据类型映射
C数据类型表示的意义
char无符号8位字节数据
short有符号16位半字数据
int有符号32位字数据
long有符号32位字数据
long long有符号64位双字数据
ARM指令集中,无论是数据处理指令还是数据加载/存储指令,处理的数据类型不同,指令的执行效率是不一样的。本章将详细讨论,如何在程序中为变量分配合理的数据类型,来提高代码的执行效率。
14.8.1 局部变量
ARM属于RISC的体系结构,所有大多数的数据处理都是在32位的寄存器中进行的。基于这个原因,局部变量应尽可能使用32位数据类型int或long。
注意一些情况下不得不使用char或short类型,例如要使用char或short类型的数据溢出指令时归零特性时,如模运算255+1=0,就要使用char类型。
为了说明局部变量类型的影响,先来看一个简单的例子。
char charinc (char a)
{
return a + 1;
}
编译出的结果如下。
charinc
ADD a1,a1,#1
AND a1,a1,#&ff
MOV pc,lr
再把上面的程序段中变量a声明位int型,代码如下。
int wordinc (int a)
{
return a + 1;
}
比较一下编译器输出结果。
wordinc
ADD a1,a1,#1
MOV pc,lr
分析上面的两段代码不难发现,当把变量声明为char型时,编译器增加了额外的ADD指令来保证其范围在0~255之间。
14.8.2 有符号数和无符号数
上一节讨论了对于局部变量和函数参数,使用int型比使用char或short型要好。本节将对程序中的有符号整数(signed int)和无符号整数(unsigned int)的执行效率进行分析比较。
首先来看上一节的例子,如果将变量指定为有符号的半字类型(编译器默认short型为有符号类型),程序的源代码如下。
short shortinc (short a)
{
return a + 1;
}
编译后的结果如下。
shortinc
ADD a1,a1,#1
MOV a1,a1,LSL #16
MOV a1,a1,ASR #16
MOV pc,lr
分析发现,该结果比使用int型的变量多增加了两条指令(LSL和ASR)。编译器先将变量左移16位,然后右移16位,以实现一个16位符号扩展。右移是符号位扩展移位,它复制了符号位来填充高16位。
通常情况下,如果程序中只有加法、减法和乘法,那么有符号和无符号数的执行效率相差不大。但是,如果有了除法,情况就不一样了。详细内容可参加除法运算优化一节。
14.8.3 全局变量
1.边界对齐
对于RISC体系结构的处理器来说,访问边界对齐的数据要比访问非对齐的数据更高效。表14.3显示了ARM结构下各数据类型所占的字节数。
表14.3 各数据类型所占字节数
C数据类型所占字节数
char,singed char,unsigned char1
short,unsigned short2
int,unsigned int,long,unsigned long4
float4
double4
long long4
变量定义虽然很简单,但是也有很多值得注意的地方。先看下面的例子。
定义1:
char a;
short b;
char c;
int d;
定义2:
char a;
char c;
short b;
int d;
这里定义的4个变量形式都一样,只是次序不同,却导致了在最终映像中不同的数据布局,如同14.1所示,其中pad为无意义的填充数据。
![高效的C编程之变量类型](/uploads/allimg/171017/2362486-1G01GAK62N.png)
图14.1 变量在数据区里的布局
从图中可以看出,第二种方式节约了更多的存储器空间。
由此可见,在变量声明的时候需要考虑怎样最佳的控制存储器布局。当然,编译器在一定程度上能够优化这类问题,但最好的方法还是在编译的时候把所有相同类型的变量放在一起定义。
2.访问外部变量
首先来看一个例子。下面的例子定义了一些全局变量,在main( )中为这些变量赋值并将其打印输出。
/************
* access.c *
************/
#include 《stdio.h》
char tx;
char rx;
char byte;
char c;
unsigned state;
unsigned flags;
int main ()
{ tx = 1;
rx = 2;
byte = 3;
c = 4;
state = 5;
flags = 6;
printf(“%u %u %u %u %u %u\n”, tx, rx, byte, c, state, flags);
return 0;
}
使用armcc编译,生成的代码大小如下。
C$$code 132
C$$data 12
如果将全局变量声明为extern,变量的定义在其他文件中,那么生成的代码量将有所增加。
将全局变量声明为extern,生成的代码大小如下。
C$$code 168
C$$data 12
这是因为当将变量声明为extern后,每次访问变量编译器都将从内存重新加载,而不是使用内存偏移,直接访问。
下图显示编译器对声明为extern变量的访问。
解决的办法是将要从外部引用的extern变量定义在一个结构体中。在程序中通过结构体访问外部变量。具体用法如下例所示。
/*************
* globals.h *
*************/
/* DECLARATIONS of globals - included in all sources */
#ifdef __arm
struct globs
{ char tx;
char rx;
![高效的C编程之变量类型](/uploads/allimg/171017/2362486-1G01GAR25K.png)
图14.2 对extern变量的访问
char byte;
char c;
unsigned state;
unsigned flags;
};
extern struct globs g;
#define tx g.tx
#define rx g.rx
#define byte g.byte
#define c g.c
#define state g.state
#define flags g.flags
#else
extern char tx;
extern char rx;
extern char byte;
extern char c;
extern unsigned state;
extern unsigned flags;
#endif
/*************
* globals.c *
*************/
/* DEFINITIONS of globals - single source file */
#ifdef __arm
# include “globals.h”
struct globs g;
#else
char tx;
char rx;
char byte;
char c;
unsigned state;
unsigned flags;
#endif
/************
* access.c *
************/
#include 《stdio.h》
#include “globals.h”
int main ()
{tx = 1;
rx = 2;
byte = 3;
c = 4;
state = 5;
flags = 6;
printf(“%u %u %u %u %u %u\n”, tx, rx, byte, c, state, flags);
return 0;
}
将变量定义在结构体内有以下几点好处。
· 全局变量使用更小的内存空间。(没有使用结构体占有24字节,而使用结构体之后只占有12字节)
· 全局变量被放置在ZI段而不是RW段,这样就减少了ROM映像文件的大小。
ARM C编译器支持基本的数据类型:char、short、int、long long、float和double。表14.2说明了armcc对C语言所使用的数据类型的映射。
表14.2 C编译器数据类型映射
C数据类型表示的意义
char无符号8位字节数据
short有符号16位半字数据
int有符号32位字数据
long有符号32位字数据
long long有符号64位双字数据
ARM指令集中,无论是数据处理指令还是数据加载/存储指令,处理的数据类型不同,指令的执行效率是不一样的。本章将详细讨论,如何在程序中为变量分配合理的数据类型,来提高代码的执行效率。
14.8.1 局部变量
ARM属于RISC的体系结构,所有大多数的数据处理都是在32位的寄存器中进行的。基于这个原因,局部变量应尽可能使用32位数据类型int或long。
注意一些情况下不得不使用char或short类型,例如要使用char或short类型的数据溢出指令时归零特性时,如模运算255+1=0,就要使用char类型。
为了说明局部变量类型的影响,先来看一个简单的例子。
char charinc (char a)
{
return a + 1;
}
编译出的结果如下。
charinc
ADD a1,a1,#1
AND a1,a1,#&ff
MOV pc,lr
再把上面的程序段中变量a声明位int型,代码如下。
int wordinc (int a)
{
return a + 1;
}
比较一下编译器输出结果。
wordinc
ADD a1,a1,#1
MOV pc,lr
分析上面的两段代码不难发现,当把变量声明为char型时,编译器增加了额外的ADD指令来保证其范围在0~255之间。
14.8.2 有符号数和无符号数
上一节讨论了对于局部变量和函数参数,使用int型比使用char或short型要好。本节将对程序中的有符号整数(signed int)和无符号整数(unsigned int)的执行效率进行分析比较。
首先来看上一节的例子,如果将变量指定为有符号的半字类型(编译器默认short型为有符号类型),程序的源代码如下。
short shortinc (short a)
{
return a + 1;
}
编译后的结果如下。
shortinc
ADD a1,a1,#1
MOV a1,a1,LSL #16
MOV a1,a1,ASR #16
MOV pc,lr
分析发现,该结果比使用int型的变量多增加了两条指令(LSL和ASR)。编译器先将变量左移16位,然后右移16位,以实现一个16位符号扩展。右移是符号位扩展移位,它复制了符号位来填充高16位。
通常情况下,如果程序中只有加法、减法和乘法,那么有符号和无符号数的执行效率相差不大。但是,如果有了除法,情况就不一样了。详细内容可参加除法运算优化一节。
14.8.3 全局变量
1.边界对齐
对于RISC体系结构的处理器来说,访问边界对齐的数据要比访问非对齐的数据更高效。表14.3显示了ARM结构下各数据类型所占的字节数。
表14.3 各数据类型所占字节数
C数据类型所占字节数
char,singed char,unsigned char1
short,unsigned short2
int,unsigned int,long,unsigned long4
float4
double4
long long4
变量定义虽然很简单,但是也有很多值得注意的地方。先看下面的例子。
定义1:
char a;
short b;
char c;
int d;
定义2:
char a;
char c;
short b;
int d;
这里定义的4个变量形式都一样,只是次序不同,却导致了在最终映像中不同的数据布局,如同14.1所示,其中pad为无意义的填充数据。
![高效的C编程之变量类型](/uploads/allimg/171017/2362486-1G01GAK62N.png)
图14.1 变量在数据区里的布局
从图中可以看出,第二种方式节约了更多的存储器空间。
由此可见,在变量声明的时候需要考虑怎样最佳的控制存储器布局。当然,编译器在一定程度上能够优化这类问题,但最好的方法还是在编译的时候把所有相同类型的变量放在一起定义。
2.访问外部变量
首先来看一个例子。下面的例子定义了一些全局变量,在main( )中为这些变量赋值并将其打印输出。
/************
* access.c *
************/
#include 《stdio.h》
char tx;
char rx;
char byte;
char c;
unsigned state;
unsigned flags;
int main ()
{ tx = 1;
rx = 2;
byte = 3;
c = 4;
state = 5;
flags = 6;
printf(“%u %u %u %u %u %u\n”, tx, rx, byte, c, state, flags);
return 0;
}
使用armcc编译,生成的代码大小如下。
C$$code 132
C$$data 12
如果将全局变量声明为extern,变量的定义在其他文件中,那么生成的代码量将有所增加。
将全局变量声明为extern,生成的代码大小如下。
C$$code 168
C$$data 12
这是因为当将变量声明为extern后,每次访问变量编译器都将从内存重新加载,而不是使用内存偏移,直接访问。
下图显示编译器对声明为extern变量的访问。
解决的办法是将要从外部引用的extern变量定义在一个结构体中。在程序中通过结构体访问外部变量。具体用法如下例所示。
/*************
* globals.h *
*************/
/* DECLARATIONS of globals - included in all sources */
#ifdef __arm
struct globs
{ char tx;
char rx;
![高效的C编程之变量类型](/uploads/allimg/171017/2362486-1G01GAR25K.png)
图14.2 对extern变量的访问
char byte;
char c;
unsigned state;
unsigned flags;
};
extern struct globs g;
#define tx g.tx
#define rx g.rx
#define byte g.byte
#define c g.c
#define state g.state
#define flags g.flags
#else
extern char tx;
extern char rx;
extern char byte;
extern char c;
extern unsigned state;
extern unsigned flags;
#endif
/*************
* globals.c *
*************/
/* DEFINITIONS of globals - single source file */
#ifdef __arm
# include “globals.h”
struct globs g;
#else
char tx;
char rx;
char byte;
char c;
unsigned state;
unsigned flags;
#endif
/************
* access.c *
************/
#include 《stdio.h》
#include “globals.h”
int main ()
{tx = 1;
rx = 2;
byte = 3;
c = 4;
state = 5;
flags = 6;
printf(“%u %u %u %u %u %u\n”, tx, rx, byte, c, state, flags);
return 0;
}
将变量定义在结构体内有以下几点好处。
· 全局变量使用更小的内存空间。(没有使用结构体占有24字节,而使用结构体之后只占有12字节)
· 全局变量被放置在ZI段而不是RW段,这样就减少了ROM映像文件的大小。
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- Windows编程之数据类型综述 5次下载
- Windows编程之变量与可变性详解 8次下载
- Windows编程之变量和常量差异综述 8次下载
- Windows编程之变量和可变性综述 3次下载
- python教程之变量和简单数据类型 7次下载
- C++程序设计教程之数据类型与表达式的详细资料说明 0次下载
- C语言教程之数据类型与运算符的详细资料说明 8次下载
- C语言实用教程之数据类型运算符和表达式的详细资料说明 10次下载
- C++入门教程之数据类型、运算符和表达式的详细资料说明 2次下载
- C语言教程之C基础变量的技术总结 11次下载
- C语言程序设计教程之基本数据类型、运算符和表达式的详细资料概述 30次下载
- 函数及变量存贮类型 0次下载
- C语言教程之显卡类型测试 0次下载
- C语言教程之获取环境变量 0次下载
- C语言教程之字符型变量的使用 0次下载
- 详解C语言变量和数据类型 876次阅读
- ARRAY 数据类型的变量 1148次阅读
- KUKA E6POS结构类型的变量定义 6420次阅读
- 变量的存储 837次阅读
- C语言的变量-2 693次阅读
- C语言的变量-1 846次阅读
- C程序流程设计之变量 723次阅读
- 什么是变量? 1151次阅读
- SCL:STRUCT和UDT类型变量的赋值 1572次阅读
- 支持处理Variant类型的变量的指令说明 2604次阅读
- PLC静态变量的作用域和生存期 3334次阅读
- C语言中变量和常量的关系 2945次阅读
- 详细解读Python变量类型 2751次阅读
- 全局变量和局部变量有什么区别 3.2w次阅读
- pic单片机io口控制教程之c语言编程实现 1.2w次阅读
下载排行
本周
- 1电子电路原理第七版PDF电子教材免费下载
- 0.00 MB | 1490次下载 | 免费
- 2单片机典型实例介绍
- 18.19 MB | 92次下载 | 1 积分
- 3S7-200PLC编程实例详细资料
- 1.17 MB | 27次下载 | 1 积分
- 4笔记本电脑主板的元件识别和讲解说明
- 4.28 MB | 18次下载 | 4 积分
- 5开关电源原理及各功能电路详解
- 0.38 MB | 10次下载 | 免费
- 6基于AT89C2051/4051单片机编程器的实验
- 0.11 MB | 4次下载 | 免费
- 7蓝牙设备在嵌入式领域的广泛应用
- 0.63 MB | 3次下载 | 免费
- 89天练会电子电路识图
- 5.91 MB | 3次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 2PADS 9.0 2009最新版 -下载
- 0.00 MB | 66304次下载 | 免费
- 3protel99下载protel99软件下载(中文版)
- 0.00 MB | 51209次下载 | 免费
- 4LabView 8.0 专业版下载 (3CD完整版)
- 0.00 MB | 51043次下载 | 免费
- 5555集成电路应用800例(新编版)
- 0.00 MB | 33562次下载 | 免费
- 6接口电路图大全
- 未知 | 30320次下载 | 免费
- 7Multisim 10下载Multisim 10 中文版
- 0.00 MB | 28588次下载 | 免费
- 8开关电源设计实例指南
- 未知 | 21539次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935053次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537791次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233045次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191183次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183277次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138039次下载 | 免费
评论