EDN博客精华文章 作者:
WoodPecker
1:_testbit_() 调令对应着JBC指令,会自动清掉测试位。_at_ 和 _nop_() 都挺好用。但是,_crol_()等循环调令就没什么意思了,循环不带Cy,不会给位操作带来方便,而且,即使只循环一位,也带个计数器,是典型的垃圾代码。
2:打开.M51文件察看内存分配情况。在Option for Target->C51中选中Keep Variable in order会使检察内存容易些。在Option for Target->Listing->Linker Listing中,只选择Memory Map和Public Symbols会使.M51减肥。
3:编译器会从0x00开始为所有的子程序分配局部变量,然后,从局部变量的最高地址+1开始分配全局变量。全局变量的最高地址+1开始是堆栈区。由于编译器不会优化内存,故idata区的下方可能会有部分空白区域被浪费,可以通过手工移动全局变量(特别是数组类型的变量)的定义相对顺序尝试解决。
4:返回bit的函数,返回值在"Cy"中。函数的bit参数,会自动安排为public,在bdata中定义。
5:使用强制类型转换可能会发生意外。
6:switch(){case...}块中最好加上"default: break;"。否则死都不知道怎么死的(未曾确认,但加上后就好了,也可能是巧合)。
7:不要在定义全局变量时赋初始值,可以在主程序开始时人工初始化。否则编译器会在Startup.A51的最后两句:MOV SP,#?STACK-1 和 LJMP ?C_START 之间加入一大堆初始化语句,效率低下,令人讨厌。
8:在Keil C51的目录下有一个文件"C51.pdf"是原版的帮助,不过,目录做的不是很详细,查找什么东西最好用Acrobat的Find功能。另外,这个文件也不是万能的,有些东西也是不清不楚。
9:C51里嵌汇编。最好不要这样做,虽然我很喜欢汇编。
因为C51编译器不象VC++那样功能强大,所以要想在汇编中加入一个循环并且使用某一个R寄存器作为循环指针,这就有点麻烦了。换句话说,就是在嵌入的汇编语句中,不可以使用局部变量。
虽然C51有它的参数传递规则,可以知道在进入当前函数时使用了那几个寄存器,在当前函数中定义局部变量又使用了哪几个寄存器,还有那几个寄存器没有用到,但是,不能保证优化程序一定将这几个寄存器保护了,它们不一定可以被安全使用的。
虽然如此,还是要将嵌入汇编的部分做一下总结:
首先,在"Project Window"中选择要加入汇编代码的".C"文件,右击,选择"Options for File ???.c"。在"Properties"页中,选中"Generate Assembler SRC File"和"Assemble SRC File",使检查框由灰色变成黑色。
然后,把"...\Keil\C51\Lib\C51S.Lib"添加到"Source Group"中。有人说该文件一定要作为工程的最后文件,倒是未必。
最后,在c函数中添加汇编语句,以 #pragma asm 开头,以 #pragma endasm 结尾。
如果汇编中有循环,可以写为如下形式:
void OutSPIByte(unsigned char m){
unsigned char i;
for(i = 8,ACC = m; i > 0; i--){
#pragma asm
clr SCK
rlc A
mov SI,C
setb SCK
nop
#pragma endasm
}
}
在for循环中,如果使用类似"i--"的递减方式,当终止条件为"i > 0"时,会生成汇编代码:
mov r6,#08H
......
djnz r6,rel
当终止条件为"i > 2"时,会生成汇编代码:
mov r6,#08H
.