仅作演示。

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.s
PRESERVE8
AREA |C$$code|, CODE, READONLY
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IMPORT cfunc_print
IMPORT c_add
IMPORT c_sub EXPORT AsmCallerAdd
EXPORT AsmCallerSub
EXPORT AsmCallerPrint
EXPORT slib_ReadCpuStatus AsmCallerAdd ; ,执行子函数TestFunc6(,)
sub r13, r13, # ;sp-=
str r14, [r13] ;sp--->lr
bl c_add ;BL : r0,r1中的参数传到子函数
ldr r14, [r13] ;lr--->sp
add r13, r13, # ;sp+=
bx r14 ;goto sp AsmCallerSub
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #
bl c_sub
ldmfd sp, {fp, sp, pc}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AsmCallerPrint
sub r13, r13, # ;sp -=
str r14, [r13] ;sp ---> lr
bl cfunc_print ;
ldr r14, [r13] ;lr ---> sp
add r13, r13, # ;sp +=
bx r14 ;goto sp slib_ReadCpuStatus
mov ip, sp
stmfd sp!, {fp, ip, lr, pc}
sub fp, ip, #
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 = ;
Uart_Printf("asm_c_ctl_cp15\n"); __asm
{
mrc p15,,r0,c1,c0,
MOV i,r0
}
return i;
} unsigned int asm_c_ReadCPSR(void)
{
unsigned int i = ;
__asm
{
mrs r0,cpsr
MOV 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中使用汇编语言操作协处理器cp15
Uart_Printf("4+5 = %d \n" , AsmCallerAdd(, ) ); //汇编调用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=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" , AsmCallerSub(, ) );//汇编调用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 :60000013 //mode[4-0] 10011 svc模式。
// this is cfunc_print,called_by_asm。
// in svc

最新文章

  1. Java的配置文件有多少种
  2. nodejs 的ajax获取数据express
  3. jQuery 点击显示再次点击隐藏
  4. MATLAB符号运算
  5. 276. Paint Fence
  6. 解析AFNetWorking 网络框架(二)
  7. ACM题集以及各种总结大全!
  8. Oracle RAC OCR 和 VotingDisk 的备份与恢复
  9. SRM 405(1-250pt, 1-500pt)
  10. LINUX 内核代码 errno 错误代码提示 /include/asm/errno.h
  11. ArcGIS网络分析之Silverlight客户端路径分析(三)
  12. Nomad入门
  13. StringUtils工具类常用方法
  14. CSS2Properties doesn't have an indexed property setter for '0'
  15. 纯HTML5APP与原生APP的差距在哪?
  16. Redis面试点
  17. Luogu4131 WC2005 友好的生物 状压DP
  18. 绍一集训Round#1
  19. python 全栈开发,Day130(多玩具端的遥控功能, 简单的双向聊天,聊天记录存放数据库,消息提醒,玩具主动发起消息,玩具主动发起点播)
  20. 获取域名,url,指定url参数的方法

热门文章

  1. 利用copy函数简单快速输出/保存vector向量容器中的数据
  2. Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数
  3. block 解析 - 成员变量
  4. uva 1561 - Cycle Game(推理)
  5. C#中析构函数,命名空间及字符串的运用(Ninth day)
  6. 一个简单链表的C++实现
  7. openstack第1天
  8. BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支( 二分答案 )
  9. linux ln 命令(转载)
  10. ajax.js