arm:c语言和汇编混合编程

仅作演示。c和汇编可相互调用,汇编子函数格式参考 汇编:普通的函数调用的汇编代码解析 http://www.cnblogs.com/mylinux/p/4139972.html

;//call_asm.s
    PRESERVE8
    AREA |C$$code|, CODE, READONLY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    IMPORT cfunc_called_by_asm
    IMPORT c_add
    IMPORT c_sub

    EXPORT AsmCaller1
    EXPORT AsmCaller2
    EXPORT AsmCaller3
    EXPORT slib_ReadCpuStatus

AsmCaller1              ; ,执行子函数TestFunc6(1,2)
    sub r13, r13, #4    ;sp-=4
    str r14, [r13]      ;sp--->lr
    bl c_add            ;BL : r0,r1中的参数传到子函数
    ldr r14, [r13]      ;lr--->sp
    add r13, r13, #4    ;sp+=4
    bx r14              ;goto sp

AsmCaller2
    mov     ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub     fp, ip, #4
    bl      c_sub
    ldmfd   sp, {fp, sp, pc}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AsmCaller3
    sub r13, r13, #4    ;sp -= 4
    str r14, [r13]      ;sp ---> lr
    bl cfunc_called_by_asm    ;
    ldr r14, [r13]      ;lr ---> sp
    add r13, r13, #4    ;sp += 4
    bx r14              ;goto sp

slib_ReadCpuStatus
    mov     ip, sp
    stmfd   sp!, {fp, ip, lr, pc}
    sub     fp, ip, #4
    mrs     r0,cpsr
    ldmfd   sp, {fp, sp, pc}

    END
//asm_c.c

/*
根据“ARM-thumb 过程调用标准”:
r0-r3    用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。
         被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。
r4-r11   被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
r12      是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。
         在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。
r13      是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
r14      是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
r15      是程序计数器 PC。它不能用于任何其它用途。
         注意:在中断程序中,所有的寄存器都必须保护,编译器会自动保护R4~R11
*/

int c_add(int a ,int b)
{
    return a+b;
}
int c_sub(int a ,int b)
{
    return a-b;
}

unsigned int asm_c_ctl_cp15(void)
{
    unsigned int i = 0;
    Uart_Printf("asm_c_ctl_cp15\n");

    __asm
    {
        mrc p15,0,r0,c1,c0,0
        MOV i,r0
    }
    return i;
}

unsigned int asm_c_ReadCPSR(void)
{
    unsigned int i = 0;
    __asm
    {
        mrs     r0,cpsr
        MOV i,r0
    }
    return i;
}

void cfunc_called_by_asm()
{
    Uart_Printf("this is cfunc_called_by_asm\n");
}

void asm_demo(void)
{
    int i, j,a ;
    asm_c_ctl_cp15();
    Uart_Printf("asm_demo\n");
    Uart_Printf("4+5 = %d \n" ,  AsmCaller1(4, 5) );
    //mdk_jlink:
    //get into AsmCaller1(4, 5) :  r0=4 ,r1=5
    //get into c_add    : r0=4 ,r1=5
    //return from c_add : r0=9
    //return from AsmCaller1: r0=0x30006160 ,r1=9 .
    //函数参数从左到右是放到r0-r3,[不够再push stack]
    //push stack用stmfd ldmfd,右边的参数会先入栈
    //STMFD&&LDMFD  http://www.cnblogs.com/mylinux/p/4139972.html

    Uart_Printf("9-5 = %d \n" ,  AsmCaller2(9, 5) );
    Uart_Printf("slib_ReadCPSR :%x \n" , asm_c_ReadCPSR() );

    AsmCaller3();
    switch(0x1f & slib_ReadCpuStatus()){
        case 0x13:
            Uart_Printf("in svc\n" , a);
    } 

}
// asm_demo
// asm_c_ctl_cp15
// 4+5 = 9
// 9-5 = 4
// slib_ReadCPSR :60000013
// this is cfunc_called_by_asm
// in svc
时间: 2024-08-04 01:18:14

arm:c语言和汇编混合编程的相关文章

【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGet()获取当前计数值.因为 系统时钟默认工作频率为60Hz,则1个tick相当于16.7ms,不符号我们的精度要求.虽然可以通过sysClkRateSet(1000),把精度提高到1ms,但1kHz的系统时钟中断频率会使得CPU的开销大增.考虑到像nanoSleep()这样的应用其计时精度可以达到纳

嵌入式Linux ARM汇编(七)——C语言与ARM汇编混合编程

嵌入式Linux ARM汇编(七)--C语言与ARM汇编混合编程 在嵌入式系统开发中,目前使用的主要编程语言是C和汇编.在大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较好,便于人的理解,而且有大量的支持库.但是很多地方还是要用到汇编语言,例如开机时硬件系统的初始化,包括CPU状态的设定,中断的使能,主频的设定,以及RAM的控制参数及初始化,一些中断处理方面也可能涉及汇编.另外一个使用汇编的地方就是一些对性能非常敏感的代码块,这是不能依靠C编译器的生成代

GNU风格ARM汇编编程实战之一 <C与汇编混合编程>

一.参考资料 1. <ARM GCC内联汇编手册>:http://www.ethernut.de/en/documents/arm-inline-asm.html 2. <__asm__ __volatile__内嵌汇编用法简述>:http://www.embedu.org/Column/Column28.htm 3. <A?R?M?内?嵌?汇?编?示?例>:http://wenku.baidu.com/view/72c12e4133687e21af45a990.htm

37.C与汇编混合编程

37.C与汇编混合编程 新建light.c: 修改start.S: 修改Makefile:加light.o 最后make成功,烧写成功. 同样,我们也可以在C函数里调用我们的汇编里面的函数: 修改start.S:把light_led申明为global: 在light.c中被调用: Make编译烧写到开发板:发现灯是可以被点亮的.在C中调用汇编函数成功. 接下来的是在C中嵌入汇编代码,而不是调用: C中嵌入汇编代码: 格式: C内嵌汇编以关键字"__asm__"或者"asm&q

kermit配置/反汇编/c和汇编混合编程/计算机存储介质/GPIO编程

kermit配置 反汇编 [email protected]:~/1$ gcc hello.c  -o app [email protected]:~/1$ gcc hello.c -g -o app -g参数决定反汇编之后的文件中,还能否看到c代码 [email protected]:~/1$ objdump -dSsx app > file 两种情况下, cat file. 查看文件内容,c代码出会不一样. [email protected]:~/1$ file app app: ELF 6

Arm中的c和汇编混合编程

1.c调汇编注意:去掉汇编的入口entry.形参通过寄存器R0~R3保存,超出四个通过栈传递. 2.汇编调c:形参通过R0~R3传递,返回值保存在R0, 3.c中内嵌汇编,_asm{ 汇编代码 },从程序可移植角度,尽量选择单独一个文件写汇编. 4.bsp 板级支持包,bootloader+操作系统+外设驱动 5.读写速度:寄存器>cache(SRAM)>SDRAM,DDRAM>flash(norflash,nandflash)>网盘

5种语言混合编程:C++、JS、python、Lisp、汇编

/* 混合C++.JS.python.Lisp.汇编 1种语言,5种语法 */ main { //C++ vector<int> v; v.push(2); putsl(v.size()); if(v.count()==1) { putsl("abc"); } //JS var a=function(x){ return x*2; } putsl(a(3)); a={90,91}; putsl(a[1]); //python b=2 if b==2 putsl 1 puts

32位汇编第七讲,混合编程,内联汇编

32位汇编第七讲,混合编程 博客园IBinary原创 QQ:2510908331  博客连接:http://www.cnblogs.com/iBinary/ 转载请注明出处,谢谢 混合编程的概念,有时候我们会想,C语言可不可以调用汇编的函数,或者反过来调用 或者说C语言里面内部直接内联汇编去编写. 可以实现,静看怎么实现 一丶C语言调用汇编语言的函数 1.创建工程和代码 ①创建VC++控制台程序 FILE(文件) - NEW (新建) 然后我们打开源文件,一级一级展开,找到我们的main函数 那

extern &quot;C&quot; 的含义:????实现C++与C及其它语言的混合编程

C++中extern "C"的设立动机是实现C++与C及其它语言的混合编程. C++为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同.对于函数void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字. extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中对本