您的位置:首页 > 编程语言

C与汇编混合编程

2017-08-15 09:04 218 查看
一、为什么需要混合编程

①汇编语言:执行效率高;编写繁琐

C语言:可读性强,移植性好,调试方便

什么时候需要使用汇编:

1. 执行效率

2. 能够更直接地控制处理器

二、混合编程类型
1.汇编调用[b]C[/b]函数

ldr pc, =xxxxxxxxx
2.C调用汇编函数
start.S中修改

#define GPBCON 0x56000010

#define GPBDAT 0x56000014

.global light_led                                 修改light_led设置为全局变量

light_led:

    ldr r0, =GPBCON

    ldr r1, =0x15400

    str r1, [r0]

    ldr r0, =GPBDAT

    ldr r1, =0x6bf

    str r1, [r0]

    mov pc, lr

main.c中

#define GPBCON (volatile unsigned long*) 0x56000010

#define GPBDAT (volatile unsigned long*) 0x56000014

int gboot_main()

{

/*    *(GPBCON) = 0x15400;

    *(GPBDAT) = 0x6bf;

*/

    light_led();                                    调用了start.S中的light_led

    return 0;

}

3.C内嵌汇编
[b]3.1 C[/b]内嵌汇编[b]-[/b]格式
__asm__(
汇编语句部分

:输出部分

:输入部分

:破坏描述部分

);

C内嵌汇编以关键字”__asm__”或”asm”开始,下辖四个部分,各部分之间使用":"分开, 第一部分是必须写的,后面三部分是可以省略,但是分号:不能省略!

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

[b]3.2 C[/b]内嵌汇编[b]-[/b]范例

void write_p15_c1 (unsigned long value)

{

__asm__(

“mcr p15, 0, %0, c1, c0, 0\n”

:

: “r” (value) @编译器选择一个R*寄存器

: "memory");

}

unsigned long read_p15_c1 (void)

{

unsigned long value;

__asm__(

“mrc p15, 0, %0, c1, c0, 0\n”

: “=r” (value) @ ’=‘ 表示只写操作数,用于输出部

:

: "memory");

return value;

}


[b]3.3 C
[/b]内嵌汇编[b]-[/b]优化

使用volatile来告诉编译器,不要对接下来的这部分代码进行优化。

unsigned long old;

unsigned long
bb93
temp;

__asm__ volatile(

"mrs %0, cpsr \n"

"orr %1, %0, #128 \n“

"msr cpsr_c, %1\n"

: "=r“ (old), "=r“ (temp)

: :

"memory

3.4使用内嵌汇编点亮LED

main.c

//#define GPBCON (volatile unsigned long*) 0x56000010

//#define GPBDAT (volatile unsigned long*) 0x56000014

#define GPBCON 0x56000010

#define GPBDAT 0x56000014

int gboot_main()

{

//    *(GPBCON) = 0x15400;

// *(GPBDAT) = 0x6bf;

//    light_led();

    __asm__(

            "ldr r1, =0x15400\n"

            "str r1, [%0]\n"

            "ldr r1, =0x6bf\n"

            "str r1, [%1]\n"

            :

            :"r"(GPBCON),"r"(GPBDAT)                      输入部分第一个是GPBCON,第二个是GPBDAT

            :"r1"                                         告诉系统修改了r1寄存器

    );

    return 0;

}


<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中的“错误:找不到或...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: