嵌入式C编程技术

2008-02-23 05:32:05来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

二、 C语言技巧
这部分内容包括公用表达式处理、指针的使用、循环的使用连同函数返回地址的控制。
1? 公用表达式处理
(1) 消除公用表达式
在编写程式完成某些计算的过程中,有时会把同样的运算结果赋值给不止1个变量,
然后在后续的计算中使用。随着程式变大和复杂性的增加,最后可能一次次进行相
同的运算而并不知道。下面是1个把变量i,j,k运算结果赋给变量a,b,c的函数。包
含此函数的程式以列表文档的形式给出,这样能够看到程式的行号、相应行所对应
汇编程式连同存储器的使用情况。

程式1:
1 void func1(int i,int j)
2 {
3 1 int k=20;
4 1 int a,b,c;
5 1 a=i*j/k;
6 1 b=i*j/k;
7 1 c=i*j/k;
8 1 };

FUNCTIONfunc1 (BEGIN)
0000 8E00RMOV i,R6
0002 8F00RMOV i 01H,R7;
;......|Variable 'j ' assigned to ReGISter 'R2/R3'......
0004 AB05 MOV R3,AR5
0006 AA04 MOV R2,AR4;
SOURCE LINE # 1
; SOURCE LINE # 2
; SOURCE LINE # 3
0008 750000 R MOV k,#00H
000B 750014 R MOV k 01H,#014H;
;SOURCE LINE # 5
000E 120000 E LCALL ? C_IMUL
0011 AC00 R MOV R4,k
0013 AD00 R MOV R5,k 01H
0015 120000 E LCALL ? C_SIDIV
0018 8E00 R MOV a,R6
001A 8F00 R MOV a 01H,R7
;SOURCE LINE # 6
001C 8E00 R MOV b,R6
001E 8F00 R MOV b 01H,R7
;SOURCE LINE # 7
0020 8E00 R MOV c,R6
0022 8F00 R MOV c 01H,R7
;SOURCE LINE # 8
0024 22 RET
; FUNCTION func1 (END)

MODULE INFORMATION:STATIC OVERLAYABLE
CODE SIZE= 37 ---
CONSTANT SIZE=--- ---
XDATA SIZE=--- ---
PDATA SIZE=--- 10
DATA SIZE=--- ---
IDATA SIZE=--- ---
BIT SIZE=--- ---
END OF MODULE INFORMATION.

程式2:
1 void func2(int i,int j)
2 {
3 int k=20;
4 int a,b,c;
5 a=b=c=i*j/k;
6 }

;FUNCTION func2(BEGIN)
;--- Variable 'i ' assigned to Register 'R6/R7' ---
;--- Variable 'j ' assigned to Register 'R4/R5' ----
;SOURCE LINE # 1
;SOURCE LINE # 2
;SOURCE LINE # 3
0000 750000 R MOV k,#00H
0003 750014 R MOV k 01H,#014H
;SOURCE LINE # 5
0006 120000 E LCALL ? C_IMUL
0009 AC00 R MOV R4,k
000B AD00 RMOV R5,k 01H
000D 120000 E LCALL ?CSIDIV
0010 8E00 R MOV c,R6
0012 8F00 R MOV c 01H,R7
0014 8E00 R MOV b,R6
0016 8F00 R MOV b 01H,R7
0018 8E00 R MOV a,R6
001A 8F00 R MOV a 01H,R7
;SOURCE LINE # 6
001C 22 RET
; FUNCTION_func2 (END)

MODULE INFORMATION:STATIC OVERLAYABLE
CODE SIZE= 29 ----
CONSTANT SIZE=--- -----
XDATA SIZE=---- ----
PDATA SIZE=--- -----
DATA SIZE=---- 8
IDATA SIZE=---- ----
BIT SIZE=--- -----
END OF MODULE INFORMATION.

程式1的"func1()"有多个赋值表达式,每次(i*j/k)重新计算并把结果赋
给1个变量。在这个函数中,(i*j/k)计算3次,每次产生相同的结果。这样,
很浪费处理时间。

程式2的"func2()"把多个赋值表达式合并成1个,完成的处理过程如下:首
先,计算(i*j/k);然后,把这个结果赋给变量c,这个结果也赋给变量b和a。
用这种方法,(i*j/k)只计算一次。

值得注意的是:程式1产生的代码是经过优化处理的。好的编译器能够完成公
用表达式的自动消除。这通过使用优化选项(OPTIMIZE)实现。Franklin
C51可支持5级代码优化。OPTIMIZE也能够控制对某一函数的代码优化,如下:

#pragma OPTIMIZE(4)
func( )
{

}
# pragma OPTIMIZE(5)

这样就能够在源程式中控制函数的优化等级。程式1的代码即使是优化生成的,
他也比程式2产生的代码略长。因而,在编写程式过程中要注意消除公用表达式,
以减轻编译程式的负担,提高产生代码的效率。

"消除公用表达式"是减少处理时间的1种方法,他也能够看作是以"减少表达式的
计算次数"来减少处理时间。上面只是1个特例。实际的程式可能是要有相同的计
算,但不是连续出现。这种情况下,应该把相同表达式的处理结果赋给1个变量,
然后,在以后的使用过程中访问这个变量,程式如下:

程式1:
1 void func1(int i,int j)
2 {
3 1 Int k=20;
4 1 int a,b,c;
5 1 a=(i>>4) j-k;
6 1 b=(i>>4) j k;
7 1 c=((i>>4) j)*k;
8 1}

程式2:
1 void func2(int i,int j)
2 {
3 1 int k=20;
4 1 int a,b,c,d;
5 1 a=(d=(i>>4) j)-k;
6 1 b=d k;
7 1 c=d*k;
8 1 }
9 在程式1中,((i>>4) j)这个表达式被计算多次;而程式2中,((i>>4) j)的计算
值在第1次出现时就赋给了变量d。以后再碰到相同的计算时,直接使用变量d。

(2) 简化循环
这部分讨论对循环中连续操作的处理以减少循环的运行时间。

在C语言中,"for","while"和"do-while"循环用于重复处理。循环可用于访问1个
变量,完成获得相同结果的计算或进行循环条件的判决。

下面是通过减少不变的处理来减少循环运行时间的方法。

程式1:
1 #define uchar unsigned char
2 #define uint unsigned int
3 #define LEN
4
5 void fun1(uint a,uint b)
6 {
7 1 uchar i;
8 1 uint mem[LEN];
9 1
10 1 for(i=0;i<LEN;i )
11 1 mem[i]=a/b 10;
12 1 }

MODULE INFORMATION:STATIC OVERLAYABLE
CODE SIZE= 49 ----
CONSTANT SIZE=---- ----
XDATA SIZE=---- ----
PDATA SIZE=---- ----
DATA SIZE=---- 44
IDATA SIZE=---- ----
BIT SIZE=---- ----
END OF MODULE INFORMATION.

程式2:

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C Builder 访问 USB 口的方法

下一篇: 嵌入式系统的构建