首页 > 代码库 > arm:c语言和汇编混合编程

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

 

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