arm:c语言和汇编混合编程
时间:11-09
来源:互联网
点击:
仅作演示。
1.C和汇编可相互调用,汇编子函数格式参考汇编:普通的函数调用的汇编代码解析http://www.cnblogs.com/mylinux/p/4139972.html
本文演示了 : 汇编嵌入到c语言;
汇编调用c语言,c语言调用汇编。
2.C函数参数从左到右是放到r0-r3,[不够再push stack];push stack用stmfd ldmfd,右边的参数会先入栈。
;//call_asm.sPRESERVE8AREA C$$code, CODE, READONLY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IMPORT cfunc_printIMPORT c_addIMPORT c_subEXPORT AsmCallerAddEXPORT AsmCallerSubEXPORT AsmCallerPrintEXPORT slib_ReadCpuStatusAsmCallerAdd ; ,执行子函数TestFunc6(1,2)sub r13, r13, #4 ;sp-=4 str r14, [r13] ;sp>lrbl c_add ;BL : r0,r1中的参数传到子函数ldr r14, [r13] ;lr>sp add r13, r13, #4 ;sp+=4 bx r14 ;goto spAsmCallerSub mov ip, spstmfd sp!, {fp, ip, lr, pc}sub fp, ip, #4bl c_subldmfd sp, {fp, sp, pc} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AsmCallerPrint sub r13, r13, #4 ;sp -= 4 str r14, [r13] ;sp > lrbl cfunc_print ; ldr r14, [r13] ;lr > sp add r13, r13, #4 ;sp += 4 bx r14 ;goto spslib_ReadCpuStatusmov ip, spstmfd sp!, {fp, ip, lr, pc}sub fp, ip, #4mrs r0,cpsrldmfd 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,cpsrMOV i,r0}return i;}void cfunc_print(){Uart_Printf("this is cfunc_print,called_by_asm\n");}void asm_demo(void){int i, j,a ;Uart_Printf("asm_demo\n");asm_c_ctl_cp15();//在c中使用汇编语言操作协处理器cp15Uart_Printf("4+5 = %d \n" , AsmCallerAdd(4, 5) ); //汇编调用c语言函数//mdk_jlink://get into AsmCallerAdd(4, 5) : r0=4 ,r1=5 //get into c_add : r0=4 ,r1=5 //return from c_add : r0=9//return from AsmCallerAdd: r0=0x36160 ,r1=9 .//函数参数从左到右是放到r0-r3,[不够再push stack]//push stack用stmfd ldmfd,右边的参数会先入栈//STMFD&&LDMFD http://www.cnblogs.com/mylinux/p/4139972.htmlUart_Printf("9-5 = %d \n" , AsmCallerSub(9, 5) );//汇编调用c语言函数Uart_Printf("slib_ReadCPSR :%x \n" , asm_c_ReadCPSR() ); //在c语言中混合汇编,读取Cpsr寄存器AsmCallerPrint();//汇编调用c语言函数switch(0x1f & slib_ReadCpuStatus()){//c语言调用汇编编写的函数case 0x13:Uart_Printf("in svc\n" , a);} }// asm_demo// asm_c_ctl_cp15// 4+5 = 9 // 9-5 = 4 // slib_ReadCPSR :60013 //mode[4-0] 10011 svc模式。// this is cfunc_print,called_by_asm。// in svc
armc语言汇编混合编 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)