Chinaunix首页 | 论坛 | 博客
  • 博客访问: 412292
  • 博文数量: 93
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 1052
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-19 11:01
文章分类

全部博文(93)

文章存档

2011年(1)

2009年(26)

2008年(66)

我的朋友

分类:

2008-04-05 22:44:11

|
 
    一般用户应用程序采用C编码,C代码有良好的结构性、可读性,而且支持库丰富。汇编代码当然也有它的用武之地:
   √ 上电复位后内核及目标板的初始化;
   √ 开关中断及关键中断服务例程;
   √ 敏感代码块;

1、在C代码中嵌入汇编代码
   在C中嵌入汇编一般有两种方式:内联式(InLine Assemble)和嵌入式(Embedded Assemble)。内联式指利用__asm关键词直接在C代码中嵌入汇编代码,如:
    __asm
    {
      ... ...
    }
   嵌入式汇编形式上表现为独立定义的函数体,参数传递遵行ATPCS标准。如:
    __asm int add(int i, int j)
    {
      ADD R0, R0, R1
      MOV PC, LR
    }

   本日志后续部分以参数传递为焦点,基于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代码最终都”摇身一变“成汇编指令流,整个项目工程都被汇编”一统天下“

阅读(1731) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~