分类:
2008-04-05 22:44:11
| |
一般用户应用程序采用C编码,C代码有良好的结构性、可读性,而且支持库丰富。汇编代码当然也有它的用武之地:
√ 上电复位后内核及目标板的初始化;
√ 开关中断及关键中断服务例程; √ 敏感代码块; 1、在C代码中嵌入汇编代码 本日志后续部分以参数传递为焦点,基于C代码中的函数名与汇编代码中的标号在某些方面等价的基础上进行陈述。 2、C代码流调用汇编函数
假设汇编函数在xxxx.s文件中以标号xxxx的形式存在,若外部模块C代码流中需调用该标号,必须: √ 在xxx.s文件中以"EXPORT xxxx"声明; √ 在外部模块C代码中调用前以"extern 返回值类型 xxxx(参数1,参数2,...);"或"extern void xxxx(void);"声明; ——-汇编代码并不标识该标号处的汇编函数带参或有返回值,若存在参数传递,汇编函数必须遵照ATPCS标准操作传入参数编制指令流并输出操作结果。下面是一个例子: /* .c文件中抓出的碎片 */
extern void STRCOPY(char *dest, const char *srs); ... ... int main(void) { const char *src = “Source”; char dest[10]; ... STRCOPY(dest, src); ... } /* .s文件中抓出的碎片 */ AREA StrOperation, CODE, READONLY EXPORT STRCOPY STRCOPY LDRB R2, [R1], #1 STRB R2, [R0], #1 CMP R2, #0 BNE strcopy MOV PC, LR END 3、汇编代码流调用C函数
假设C函数在yyyy.c文件中以函数名yyyy的形式存在,若外部模块汇编代码流中需调用该函数,必须: √ 在yyyy.c文件以关键词“extern”声明并定义; √ 在外部模块汇编代码中调用前以“IMPORT yyyy”声明; ——-若C函数带参且有返回值,其参数传递遵照ATPCS标准,也即在使用“BL yyyy”指令调用C函数前必须将传入C函数的参数遵行ATPCS标准准备妥当。以下是一个例子: /* .s文件中抓出的碎片 */
AREA SWI_Function, CODE, READONLY EXPORT SWI_Handler_Ex IMPORT SWI_Exception_Function SWI_Handler_Ex STMFD sp!, {r0-r3, r12, lr} ;// STMDB,保护现场 MOV r1, sp ;// 若SWI调用带参,将R1指向第一个参数 ;// 遵照ATPCS标准,第一个参数存于R0中 MRS r0, spsr STMFD sp!, {r0} ;// spsr入栈 LDR r0, [lr,#-4] ;// 获取SWI指令码 BIC r0, r0, #0xFF000000 ;// 获取SWI number ;// r0 now contains SWI number ;// r1 now contains pointer to stacked registers BL SWI_Exception_Function ;// 调用C编写的SWI处理函数 LDMFD sp!, {r0} MSR spsr_cf,r0 ;// spsr出栈 LDMFD sp!, {r0-r3, r12, pc}^ ;// 恢复现场 END /* .c文件中抓出的碎片 */
extern void SWI_Exception_Function(int swi_num,int *reg) { while ( 1 ); ;// 替换为用户代码 } 4、”汇编代码流调用C函数“、”C代码流调用汇编函数“本质上并没有什么分别,ADS编译环境遵行ATPCS标准C代码最终都”摇身一变“成汇编指令流,整个项目工程都被汇编”一统天下“ |