END
bcfstatus,5
那类圆式比力贫苦,若是对某一模块的履行效力要求较高时,可以采纳那类法子;然则,为了汇编法式能正常运转,必需严酷遵照函数参数传递和返回法则。固然,为制止那些法则带来的贫苦,普通环境下,可以先用C说话年夜致编写一个相似功效的函数,预先界说好种种变量,采取PICC-S选项对法式停止编译,然背工工优化编译器收生的汇编代码后将其作为的模块便可以了。
①尽可能利用无符号数和字节变量。
#asm
asm(NOP);
unsignedcharbank1var2;//不法声明
processor16C84
movwf(((?a_main+1)))
例如,若是正在C模块中利用汇编模块中的函数,那末正在C中可知下声明:
movwf(((?a_add_function+0)))
unsignedcharvar1;//声明
今朝,正在市场上利用最普遍的应当属于8位单片机,MicrochipTechnoloogy公司推出的8位PIC系列单片机,今朝正在国内市场上深受用户接待,已逐步成为单片机利用的新潮水;但遗憾的是,今朝国内先容它的C说话开辟对象的册本和文章却比力少,并且用的人也不多,广年夜的法式员正在用其开辟的进程中都正在渐渐探索,大概会走一些直。笔者比来正在用PIC的C说话时就碰到了好些题目,正在那里想和比来一段工夫用PIC的C说话的一些经历和广年夜的底层硬件法式员做一下交换和先容希看本文对用PICC开辟PIC系列单片机的人有所帮闲。
;_temp3assignedto?a_main+1
GLOBAL_rotate_left
{
rlf?a_rotate_left,w
return
SIGNAT_rotate_4201
voidmax(void)
#endasm
另中一种圆式是将汇编作为一个的模块,用汇编编译器(ASPIC)生成目的文件,然后用链接器和C说话生成的其它模块的目的文件链接正在一同。若是变量要公用时,则正在另中一个模块中申明为内部类型,并许可利用情势参数和返回值。
FNSIZE_rotate_left,1,0
引行
bcfstatus,6
bcfstatus,6
需要注重的是,以C模块中声明的函数名称,正在汇编模块中是以下划线开首的。GLOBAL界说了一个全局变量,也同等于C模块中的extern,SIGNAL强造链接器正在链接各个目的文件模块时停止类型婚配查抄,FNSIZE界说部分变量和情势参数的内存分派。
用PICC编译器开辟PIC单片机的代码源代码,今朝,正在国内用得比力多的是Hi-Tech的PICC编译器,并且今朝市场上一些国内的PIC单片机仿真器也开端撑持Hi-TechPICC编译花式;是以,本文尾要以Hi-Tech的PICC为根底,先容一下PIC的C说话的根本特性。
addwf(((?_add_function+0))),w
2函数挪用时参数的传递
4注重事项
…………
5结论
普通环境下,主法式都是用C说话编写的。C说话与汇编说话最年夜的区分正在于,汇编法式履行效力较高,由于,C说话起尾要用C编译器生成汇编代码,正在很多环境下,C编译器生成的汇编代码不如用脚工生成的汇编代码效力高。正在PICC中,可以用两种圆式正在C法式中挪用汇编法式。一种圆式是利用#asm,#endasm及asm()正在C说话中直接嵌进汇编代码,#asm和#endasm指令划分用于标示嵌进汇编法式块的开首和结属;asm()用于将单条汇编指令嵌进到编译器生成的代码中,以下所示:
tem3=add_function(temp1,temp2);
Voidmain(void)
}
}
③对有必定汇编经历的人正在开端利用PICC时,应多注重不雅看编译后收生的汇编源代码,并常常不雅看经准确编译链接后收生的映像文件(.MAP文件)。正在该文件中,具体列出了分派给变量和代码的地点和生成代码的年夜小等信息。利用者可领会代码是不是优化,变量分派是不是开理,货仓是不是溢出等,从而写出高效简练的C源代码。
unsignedcharvar4=0x02;//声明,每次挪用都初初化
GLOBAL?a_rotate_left
{
voidfunc1(void)源代码{
}
externcharrotate_left(char);
⑦如有某一代码很短的函数被多个函数常常挪用,最好将其界说为宏。由于若函数代码很短时,果为被调函数和挪用函数不正在统一代码页所收生的附加代码大概都市跨越函数代码自己的长度。
PICC编译器对部分变量及传递参数利用RAM笼盖手艺。编译时,毗连器会主动把一些不大概被同时挪用的函数的主动变量区堆叠正在一同,以到达内存的高效使用,是以其内部RAM的使用效力十分高。
_main
return
PICC编译器收生的代码正在有些时间固然比力烦琐,但构造和逻辑性很强,开辟效力年夜年夜进步,调试与都很便利。不管是从法式的开辟速度、硬件量量仍是从法式的可性和可移植性上讲,PICC的长处尽非汇编说话所能对比的。
rlf_var,f
staticunsignedcharbank1ver3;//声明
PIC的C说话变量分为部分变量和全局变量,所有变量正在利用前必需先界说后利用。全局变量是正在任何函数以中申明的、可被肆意模块利用的、正在全部法式履行时代都连结有用的变量。部分变量正在函数内部申明。部分变量有两种:主动变量和静态变量。用PICC编译器开辟PIC单片机的代码源代码缺省类型为主动变量,除非明白将其声明为静态变量。并且,所有的主动变量都被分派正在存放器页0,所以bank限制词不克不及用于主动变量,即可以用于静态的部分变量。当法式退出时,主动变量占用的空间,主动变量也就得往意义。静态变量是一种部分变量,只正在声明它的函数内部有用;但它占用流动的存储单位,而那个存储单位不会被此中函数利用,是以其它函数可以经过指针拜候或点窜静态变量的值。静态变量正在法式开端只初初化一次,是以若只正在某函数内部利用一变量,而又希看其值正在2次函数挪用时代连结稳定,为真现法式模块化,则可将其声明为静态变量。例如以下声明中,有些为,有些为不法:
PICC的C说话按ANSIC来界说,并停止了C说话的扩大。PICC和ANSIC有一个底子的区分就是,PICC不撑持函数的递回挪用。那是由于PIC单片机的货仓年夜小是由硬件决议的,资本有限,所以不撑持递回挪用。它的数据也顺从尺度C的数据构造,PICC的数据构造是以数据类型的情势呈现的。PICC编译器撑持的数据类型有位类型(bit)、无符号字符(unsignedchar)、有符号字符(signedchar)、无符号整型(unsignedint)、有符号整形(signedint)、无符号长整型(unsignedlong)、有符号长整型(signedlong)、浮点(float)和指针类型等。需要注重的是,PICC撑持的多字节数据都采取低字节正在前,高字节正在后的本则。即一个多字节数,好比int型,正在内存单位中存储挨次为低位字节存储正在地点低的存储单位。高位字节存储正在地点高的存储单位中,法式员正在用union界说变量时必定要注重那一特性。
本声明申明了要挪用的那个内部函数有一个char型情势参数,并返回一个char型的值。而rotate_left()函数的真正函数体正在内部可以被ASPIC编译的汇编模块(文件名后缀.as)中,详细代码可以以下编写:
movf(((?a_main+2))),w
利用PICC时,为了更有用地使用资本,应注重以下几点:
⑥尽可能选择全局优化编译选项。为存放器页(包罗法式存储期页里和RAM存放器页)的准确转换,PICC的编译代码中丰年夜量的变更存放器页的代码,选择全局优化PICC会优化往年夜量有闭RP0、RP1、PCLAPH所增添的变更代码,从而加速法式履行速度,并节约年夜量的法式空间。
3PICC说话和汇编说话的夹杂编程
;_temp1assignedto?a_main+2
;_temp2assignedto?a_main+0
PICC函数参数的传递是按照被传参数的长度,用W、被调函数的主动变量地区或被调函数的参数地区传递,传递代码比力高效。传递给函数的参数可以经过一个由问号“?”、下划线“_”及函数名加一个偏移量组成的标号获得。下里为一挪用乞降子法式的源泉代码:
⑤对某位变量自操作时,好比求反,弗成以直接简写,例如:!flag;编译后不克不及准确收生代码,而须写成:“flag=!flag;”
;_augendstoredfromw
_add_function
nop
asm(rlf_var,f);
④正在良多环境下,PICC不撑持类型强造转换。即正在类型不婚配时须检验编译后的汇编代码,看是不是准确,特别是对指针操作的时间必定要注重。
movwf?a_rotate_left
编译后生成的汇编法式为:
_rotate_left
bcfstatus,5
unsignedchartemp1,temp2,temp3;
fcall(_add_function)
需要注重的是,嵌进汇编不是完备意义上的汇编,是一种真汇编指令,利用时必需注重它们与编译器生成代码之间的相互影响。
1Hi-TechPICC的C说话开辟对象的说话特性
Unsignedcharadd_function(unsignedcharaugend,unsignedcharaddend);
staticunsignedcharbank1var5=0x02;//声明,但只初初化一次
return(augend+addend);
unsignedcharadd_function(unsignedcharaugend,unsignedcharaddend)
movf(((?a_main+0))),w
PSECTtext0,class=CODE,local,delta=2
movwf(((?_add_function)))
②正在存放器资本许可的环境下,对某些履行效力要求较高的仄级元彼此挪用函数顶用到的内部变量,可将其界说为全局姑且变量,编程时笼盖利用,如许可削减良多编译代码。而对间断函数内部用到的变量,可用全局变量。
movf(((?a_add_function+0))),w
}
;_augendassignedto?a_add_function+0
|
QQ空间代码 使用方法: 一、登录你的QQ空间; P.S.“QQ空间特区”每天都有精彩奉献给你! |