tiny6410裸机实验第1章--------------ARM汇编和编程基础(C与ARM汇编混合编程)

发布时间:2017-6-23 16:37:09 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"tiny6410裸机实验第1章--------------ARM汇编和编程基础(C与ARM汇编混合编程)",主要涉及到tiny6410裸机实验第1章--------------ARM汇编和编程基础(C与ARM汇编混合编程)方面的内容,对于tiny6410裸机实验第1章--------------ARM汇编和编程基础(C与ARM汇编混合编程)感兴趣的同学可以参考一下。

【说明】              在嵌入式开发中,大部分情况下我们使用C语言来编程,但是在程序的最前面一小段硬件相关的操作,以及有时候对速度要求高的地方我们仍然需要使用汇编进行编程。这就使得我们必须学会如何衔接好C和汇编,具体的有:C语言调用汇编语言的变量或者函数,汇编语言调用C语言的变量或者函数,以及在C语言中嵌入汇编语言。下面我们就分别进行介绍。   【汇编调用C语言函数】                我们后面具体的编程中,首先遇到的是汇编中调用C语言,因为我们说过,程序的最前面是用汇编写的,那么总会有一个分界点,也就是从汇编转向C语言的点,这一点显然需要从汇编语言中调用C语言,怎么做呢?                回忆上一节的内容,ATPCS规则告诉我们传递C函数参数的方法是先放寄存器,还有参数就用栈来传,OK,我们的汇编就是这么调用C函数的。                  1】在调用C语言之前需要初始化栈指针SP,所谓初始化,也就是给SP赋一个值,一般是内存中的一个地址,这样,SP就指向这个地址,栈操作就基于这个地址进行,这个地址附近的内容就是栈内容,当然啦,你必须保证这个地址附近的内存空间是可用的,也就是没有什么重要的信息在里边,不然随着进栈出栈的进行,里面的内容也就被覆盖了。                  2】如果被调用的C函数没有参数,那就直接用“bl    C函数名”就可以了,没错就这么简单。。比如下面的指令                文件a.S中               ldr sp , =8*1024             //初始化栈指针               bl   main                           //跳转到b.c的xxx函数执行               文件b.c               int xxx(void)              {                       return 0;               }               注意,也不是每次调用C函数都要初始化栈,第一次初始化就好了                3】如果被调用的C函数有参数,根据ATPCS规则就应该这么玩              文件a.S中               ldr sp, =8*1024                 //初始化栈               ldr r0, =9                             //传参数!                 bl xxx                                  //跳转过去               文件b.c               void xxx(int start)              {                 }                                 4】如果被调用的C函数有超过4个的参数,根据ATPCS规则就应该这么玩               文件a.S               mov  r0, #0                  /* start */               mov  r1, #8                  /* end */               mov  r2, #0                  /* a */               mov  r3, #0                  /* b */               ldr     sp, =6*1024 - 8               mov  r4, #0               str     r4, [sp]                /* c */               mov  r4, #1               str     r4,  [sp, #4]        /* d */               bl    xxx               文件b.c               void xxx(int start, int end, int a, int b, int c, int d)             {                       }   【汇编调用C语言变量】                在汇编中其实可以操作C语言中的变量的,但是实际上用的并不多                在b.c中                int     g_val = 5;                在a.S中                IMPORT g_val               //下面的指令中就可以用了                ldr r0, =g_val                 //这么用                是不是很简单!   【C语言中调用汇编函数】                在C语言中调用汇编语言其实也是一眼就懂                文件a.S中                delay:                        ldr  r0, =1024               在b.c中               void delay();                                 //首先要声明               int xxx()              {                     delay();              }                    //直接调用,没错不用实现 直接调用   【C语言中嵌入式汇编语言】                 GNU   C提供了一种在C语言中直接加入汇编语言的方法,                 1】最简单形式的内嵌汇编                  int xxx()                  {                          asm(                                   "mov r0, #0\n\t"                                   "mov r1, r0\n\t"                          );                          return 0;                    }                                     2】内嵌汇编的模版应该是这样的,上边的只是简化版本                   asm(code  :  output operand list  :  input operand list  :  clobber list);                   下面是C语言的一个整型变量传递给汇编,逻辑左移一位后再传递给C语言的另外一个整型变量                    asm("mov %[result], %[value], ror #1"  :  [result] "=r"(y)  : [value] "r" (x));                    每一个asm语句被冒号分成了4个部分                               1)第一个部分是汇编代码                               2)第二个部分是输出列表,每一个条目由一对[]和被他包含的符号名组成,它后面跟着限制性字符串,再后面是圆括号括着的C变量。                               3)第三个部分是输入列表,语法和输出一模一样                               4)第四个部分叫破坏符列表,指明哪些部分会在汇编代码中被改变,本例中没有用到。                               5)四个部分如果后面没有其他部分了,那么省略该部分可以连:都不用写,但是如果后面有,:不能省略,也就是如果你要省略该部分,你就保持它空 白,  但是分割的:还是要加上的。下面的例子就有input 没有 output                                    asm("msr cpsr, %[ps]" : : [ps]"r"(status));                              6)其实编译器有时候会把你写的内嵌汇编改得乱七八糟,以便和编译后的C有更好的结合,如果下面这样加入volatile 关键字就可以去掉优化                                    asm volatile("mov r0, r0");                      3】我们知道,C中变量是有大小的,比如int是4字节,char是1字节,那么要用汇编操作C中变量就要注意这些                   unsigned char    LDRB/STRB           unsigned short   LDRH/STRH           unsigned int     LDR/STR           char             LDRSB/STRSB           short            LDRSH/STRSH                     4】 上边的例子中,"=r"中,"r"是指明了后面数的属性,有以下几种,                               1)"i"    表示后面会跟一个立即数                               2)"r"    表示后面跟一个变量                               3)"m"  表示后面变量的地址                     5】上边的"=" ,是一个限制符,有以下几种,                              1)"="    表示只可写,一般用在output 列表中                              2)"+"    可读可写                              3)"&"   表示输入输出用不同的寄存器                                     6】现在我们谈谈破坏列表,破坏列表指明了汇编代码中会改变哪些东西的值,让编译器注意。                             1)"memory"   指明有些内存的内容被改变了,那么一些保存该内存内容的寄存器就应该被更新                             2)"r0"   指明寄存器r0 被改变了,那么编译器就应该在内嵌汇编前边保存该寄存器的值,在内嵌汇编后边恢复它,当然r1, r2都行,r0只是举个例子

上一篇:10个有关String的面试问题
下一篇:SDUT 1232 / POJ 1785 Binary Search Heap Construction

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。