免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1262 | 回复: 0
打印 上一主题 下一主题

ATPCS中各寄存器的使用规则及其名称 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-03 18:45 |只看该作者 |倒序浏览

参数传递规则
  • 参数不超过4个时,可以使用寄存器R0~R3来传递参数,当参数超过4个时,还可以使用数据栈来传递参数。
  • 结果为一个32位整数时,可以通过寄存器R0返回
  • 结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推。
    汇编程序、C程序及C++程序相互调用
    C 程序调用汇编程序:
    o      汇编程序的设置要遵循ATPCS 规则,保证程序调用时参数的正确传递。
    o      在汇编程序中使用EXPORT 伪指令声明本子程序,使其它程序可以调用此子程序。
    o      在C 语言程序中使用extern 关键字声明外部函数(声明要调用的汇编子程序),即可调用此汇编子程序。
    o      调用汇编的C 函数:
    o      示例
    #include
    extern void strcopy(char *d,const char *s) //声明外部函数,即要调用的汇编
                                                                  //子程序
    int main(void)
    {
      const char *srcstr=“First string-source”; //定义字符串常量
      char dstsrt[] =“Second string-destination”;//定义字符串变量
      printf(“Before copying:\n”);
      printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显示源字符串和目标字符串的内容
      strcopy(dststr,srcstr); //调用汇编子程序,R0=dststr,R1=srcstr
      printf(“After copying:\n”)
      printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显示strcopy 复制字符串结果
      return(0);
    }
    o      被调用汇编子程序:
           AREA  SCopy,CODE,READONLY
           EXPORT strcopy  ;声明汇编程序strcopy,以便外部程序引用
    strcopy              ;R0 为目标字符串的地址
                                  ;R1 为源字符串的地址 ;
           LDRB R2,[R1],#1 ;读取字节数据,源地址加1
           STRB R2,[R0],#1 ;保存读取的1 字节数据,目标地址加1
           CMP r2,#0           ;判断字符串是否复制完毕
           BNE strcopy         ;没有复制完毕,继续循环
           MOV pc,lr             ;返回
           END
    汇编程序调用C程序
    o      汇编程序的设置要遵循ATPCS 规则,保证程序调用时参数的正确传递.
    o      在汇编程序中使用IMPORT 伪指令声明将要调用的C 程序函数.
    o      在调用C 程序时,要正确设置入口参数,然后使用BL 调用.
    o      汇编调用C 程序的C 函数:
    /*函数sum5()返回5 个整数的和*/
      int sum5(int a,lit b, int c,int d,int e)
    {
      return(a+b+c+d+e); //返回5 个变量的和
    }
    o      汇编调用C 程序的汇编程序
           AREA  sample, CODE,READONLY
           IMPORT sum5      ;声明外部标号sum5,即C 函数sum5()
    CALLSUM
           STMFD SP!  {LR} ;LR 寄存器放栈
           ADD R1,R0,R0     ;设置sum5 函数入口参数,R0 为参数a
           ADD R2,R1,R0     ;R1 为参数b,R2 为参数c
           ADD R3,R1,R2,
           STR R3,[SP,# -4]!   ;参数e 要通过堆栈传递
           ADD R3,R1,R1        ;R3 为参数d
           BL sum5                ;调用sum5(),结果保存在R0
           ADD SP,SP#4         ;修正SP 指针
           LDMFD SP,PC          ;子程序返回
          
          END
    嵌入式C编程
    概述:
          C语言的优点是运行速度快、编译效率高、移
    植性好和可读性强。C语言支持模块化程序设计,支持自顶
    向下的结构化程序设计方法。因此在嵌入式程序设计中经
    常会用到C语言程序设计。
          嵌入式C语言程序设计是利用基本的C语言知识,面向
    嵌入式工程实际应用进行程序设计。也就是说它首先是C语
    言程序设计,因此必须符合C语言基本语法,只是它是面向
    嵌入式的应用而设计的程序。
    o      C语言的“预处理伪指令”在嵌入式程序设计中的应用。
    1、文件包含伪指令
          格式:
    #include 头文件名.h>      ;标准头文件
    #include “头文件名.h”         ;自定义头文件
    2、宏定义伪指令
          格式:
    # define  宏标识符   宏体
           例:
    n       #define  U32  unsigned  int
    n       #define  U16  unsigned  short
    n       #define  S32  int
    n       #define  S16  short  int
    n       #define  U8   unsigned  char
    n       #define  S8   char
    3、条件宏:先测试是否定义过某宏标识符,然后决定如何处理。这样做是为了避免重复定义。
    格式:
           #ifdef         宏标识符
                  #undef       宏标识符
                  #define       宏标识符  宏体
           #else
                  #define       宏标识符  宏体
           #endif
    例:
           #ifdef  INCLUDE_SERIAL
                  #undef  NUM_TTY
                  #define NUM_TTY                         N_UART_CHANNELS
                  #undef  CONSOLE_TTY
                  #define CONSOLE_TTY                  0              
                  #undef  CONSOLE_BAUD_RATE
                  #define CONSOLE_BAUD_RATE     115200
           #endif
    4、条件编译伪指令
    格式
           #if(条件表达式1)
           …
           #elif(条件表达式2)
           …
           #elif(条件表达式n)
           …
           #else
           …
           #endif
           这样,编译时,编译器仅对#if()…#endif之间满足某一条
    件表达式的源文件部分进行编译。
    使用寄存器变量
          当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。
    为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,
    使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的
    说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的变量
    均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。
    例:
           /* 求1+2+3+….+n的值 */
    WORD Addition(BYTE n)
    {
     register i,s=0; for(i=1;i;i++)
     {
      s=s+i;
     }
     return s;
    }
    活用位操作 (熟练掌握)
          使用C语言的位操作可以减少除法和取模的运算。在计算机程序中数
    据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的
    运算和操作,因而,灵活的位操作可以有效地提高程序运行的效率 。

    例:
         /* 方法1 */
    int i,j;
    i = 879 / 16;
    j = 562 % 32;
         /* 方法2 */
    int i,j;
    i = 879 >> 4;
    j = 562 - (562 >> 5
    例 int Ra ;//Ra[15:16]=11
    Ra &= ~(3
    C语言位运算除了可以提高运算效率外,在嵌入式
    系统的编程中,它的另一个最典型的应用,而且十分广
    泛地正在被使用着的是位间的(&)、(|)、非(~)
    操作,这跟嵌入式系统的编程特点有很大关系。
    例:
         rGPCDAT=(rGPCDAT&0xFFFFFFF0)|0x0E
         rINTMSK&=~(BIT_TIMER1)
    数据指针
         在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的
    MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力。在
    嵌入式系统的实际调试中,多借助C语言指针所具有的对绝对地址单元内容的读写能
    力。以指针直接操作内存多发生在如下几种情况:
    n       某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应于
    某特定地址;
    n       两个CPU之间以双端口RAM通信,CPU需要在双端口RAM的特定单
    元(称为mail box)书写内容以在对方CPU产生中断;
    n       读取在ROM或FLASH的特定单元所烧录的汉字和英文字模。
    例:
    int *p = (int *)0xF000FF00 ;
    *p=0xABCD;
    #define rGPACON    (*(volatile unsigned *)0x56000000);
    rGPACON=0x1234;
    关键字volatile
            一般这个修饰符用来告知编译器,被修饰的变量是个“易变的”变
    量(volatile的本意是“易变的”),防止编译器进行优化。将变量加上
    volatile修饰,则编译器保证对此变量的读写操作都不会被优化。
        用法
           1、中断服务程序中修改的供其它程序检测的变量需要加volatile。
           2、多任务环境下各任务间共享的标志应该加volatile。
           3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。

    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/70744/showart_1102469.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP