C与汇编混合编程

来源:互联网 发布:外贸整合营销 海关数据 编辑:程序博客网 时间:2024/05/21 19:30
一、为什么需要混合编程
①汇编语言:执行效率高;编写繁琐
C语言:可读性强,移植性好,调试方便

什么时候需要使用汇编:
1. 执行效率
2. 能够更直接地控制处理器

二、混合编程类型
1.汇编调用C函数
ldr pc, =xxxxxxxxx
2.C调用汇编函数
start.S中修改
  1. #define GPBCON 0x56000010
  2. #define GPBDAT 0x56000014
  3. .global light_led                                 修改light_led设置为全局变量
  4. light_led:
  5.     ldr r0, =GPBCON
  6.     ldr r1, =0x15400
  7.     str r1, [r0]

  8.     ldr r0, =GPBDAT
  9.     ldr r1, =0x6bf
  10.     str r1, [r0]
  11.     mov pc, lr
main.c中
  1. #define GPBCON (volatile unsigned long*) 0x56000010
  2. #define GPBDAT (volatile unsigned long*) 0x56000014

  3. int gboot_main()
  4. {
  5. /*    *(GPBCON) = 0x15400;
  6.     *(GPBDAT) = 0x6bf;
  7. */
  8.     light_led();                                    调用了start.S中的light_led

  9.     return 0;
  10. }
3.C内嵌汇编
3.1 C内嵌汇编-格式
__asm__(
汇编语句部分
:输出部分
:输入部分
:破坏描述部分
);
C内嵌汇编以关键字”__asm__”或”asm”开始,下辖四个部分,各部分之间使用":"分开, 第一部分是必须写的,后面三部分是可以省略,但是分号:不能省略!

1.汇编语句部分:汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符 “\n”隔开或使用分号“ ; ”隔开。
2.输出部分:在汇编中被修改的C变量列表
3.输入部分: 作为参数输入到汇编中的变量列表
4.破坏描述部分: 执行汇编指令会破坏的寄存器描述

3.2 C内嵌汇编-范例

  1. void write_p15_c1 (unsigned long value)
  2. {
  3. __asm__(
  4. “mcr p15, 0, %0, c1, c0, 0\n”
  5. :
  6. : “r” (value) @编译器选择一个R*寄存器
  7. : "memory");
  8. }

  1. unsigned long read_p15_c1 (void)
  2. {
  3. unsigned long value;
  4. __asm__(
  5. “mrc p15, 0, %0, c1, c0, 0\n”
  6. :=r” (value) @ ’=‘ 表示只写操作数,用于输出部
  7. :
  8. : "memory");
  9. return value;
  10. }

3.3 C
内嵌汇编-优化
使用volatile来告诉编译器,不要对接下来的这部分代码进行优化。
  1. unsigned long old;
  2. unsigned long temp;
  3. __asm__ volatile(
  4. "mrs %0, cpsr \n"
  5. "orr %1, %0, #128 \n“
  6. "msr cpsr_c, %1\n"
  7. : "=r“ (old), "=r“ (temp)
  8. : :
  9. "memory

3.4使用内嵌汇编点亮LED
main.c
  1. //#define GPBCON (volatile unsigned long*) 0x56000010
  2. //#define GPBDAT (volatile unsigned long*) 0x56000014

  3. #define GPBCON 0x56000010
  4. #define GPBDAT 0x56000014

  5. int gboot_main()
  6. {
  7. //    *(GPBCON) = 0x15400;
  8. // *(GPBDAT) = 0x6bf;

  9. //    light_led();

  10.     __asm__(

  11.             "ldr r1, =0x15400\n"
  12.             "str r1, [%0]\n"

  13.             "ldr r1, =0x6bf\n"
  14.             "str r1, [%1]\n"
  15.             :
  16.             :"r"(GPBCON),"r"(GPBDAT)                      输入部分第一个是GPBCON,第二个是GPBDAT
  17.             :"r1"                                         诉系统修改了r1寄存器
  18.     );
  19.     return 0;
  20. }

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(30) | 评论(0) | 转发(0) |
0

上一篇:一跃进入C大门

下一篇:MMU内容学习

相关热门文章
  • SHTML是什么_SSI有什么用...
  • 查看linux中某个端口(port)...
  • 卡尔曼滤波的原理说明...
  • shell中字符串操作
  • 关于java中的“错误:找不到或...
给主人留下些什么吧!~~