C语言与汇编语言之间的函数调用
来源:互联网 发布:韩国股市行情软件下载 编辑:程序博客网 时间:2024/05/19 01:30
教材:嵌入式系统及应用,罗蕾、李允、陈丽蓉等,电子工业出版社
- ARM 程序设计
- C与汇编之间的函数调用
- ATPCS简介
- 堆栈与寄存器在函数调用中的作用
- ATPCS关于堆栈和寄存器的使用规则
- C程序调用汇编函数实例
- 汇编程序调用C函数实例
- ATPCS简介
- CC语言和汇编语言的混合程序设计
- 内联汇编
- 嵌入式汇编
- 内联汇编与嵌入式汇编的差异
- C与汇编之间的函数调用
ARM 程序设计
C与汇编之间的函数调用
ATPCS简介
- ARM-Thumb 过程调用标准 ATPCS(ARM-Thumb Procedure Call Standard)
- ATPCS 标准既是ARM 编译器使用的函数调用规则,也是设计可被 C 程序调用的汇编函数的编写规则
堆栈与寄存器在函数调用中的作用
- 函数是通过寄存器和堆栈来传递参数和返回函数值的
- 形参和返回值都应定义在具有暂存性质的寄存器和堆栈中
ATPCS关于堆栈和寄存器的使用规则
ATPCS 规定,ARM 的数据堆栈为 FD 型堆栈,即满递减堆栈
对于参数个数不多于 4 的函数,编译器必须按参数在列表中的顺序,自左向右 为它们分配寄存器 R0~R3
其中函数返回时,R0 还被用来存放函数的返回值
如果函数的参数多于 4 个,那么多余的参数则按自右向左的顺序压入数据堆栈(参数入栈顺序与参数顺序相反)
一个浮点数可能几个整数型的寄存器进行传送
双精度和
long long
类型的参数通过两个连续的寄存器来传递,返回值通过R0和R1返回(大端系统下,R0包含高位有效字)ATPCS规定的寄存器名称及使用
RWPI:读写位置无关(编译器选项)
为确保性能,函数内部最多使用12个局部变量
寄存器的别名和特殊名称都是ARM编译器和汇编器预定义的,用户可以直接使用
C程序调用汇编函数实例
程序员代替C编译器把C函数翻译成汇编程序
下面是一个用汇编语言编写的函数,该函数把 R1 指向的数据块复制到 R0 指向的存储块
AREA Strcopy, CODE, READONLY EXPORT strcopy ;声明strcopy为导出符号strcopy LDRB R2, [R1], #1 ;R1的值为源数据首地址 STRB R2, [R0], #1 ;R0的值为目标数据块首地址 CMP R2, #0 BNE strcopy MOV PC, LR ;复制完毕,返回 END
根据参数与寄存器直接的规则,可知汇编函数 strcopy 在C程序中原型应该为:
void strcopy(char *d, const char* s);
在C语言文件中,调用 strcopy 函数的方法如下
extern void strcopy(char *d, const char * s); //声明strcopy为外部引用符号int main(void){ const char *src = “source”; char dest[10];...strcopy(dest, src); //调用汇编函数strcopy...}
汇编程序调用C函数实例
现有C函数 g() 如下
int g(int a, int b, int c, int d, int e){return a+b+c+d+e;}
汇编函数f中调用C函数g(),以实现下面的功能
int f(int i) {return –g(i, 2*i, 3*i, 4*i,5*i);}
整个汇编函数 f 的代码如下
EXPORT f AREA f, CODE, READONLYIMPORT g ;声名g为外部引用符号STR LR, [SP, #-4] ;断点存入堆栈ADD R1, R0, R0 ;(R1)= i*2ADD R2, R1, R0 ;(R2)= i*3ADD R3, R1, R2 ;(R3)= i*5STR R3, [SP, #-4] ;将(R3)即第5个参数i*5存入堆栈ADD R3, R1, R1 ;(R3)= i*4BL g ;调用C函数g(),返回值在寄存器R0中ADD SP, SP, #4 ;清栈RSB R0, R0, #0 ;函数f的返回值(R0)=0-(R0)LDR PC, [SP], #4 ;恢复断点并返回END
调用时第5个参数放在数据堆栈段,所以调用C函数后需要清栈
C/C++语言和汇编语言的混合程序设计
在 C 程序中内联或嵌入式汇编代码,以提高程序的效率
内联汇编
在 C 程序中直接编写汇编程序段而形成一个语句块,这个语句块可以使用除了 BX 和 BLX之外的全部ARM指令来编写
可以使程序实现一些不能从C获得的底层功能
void enable_IRQ(void){int tmp; _ _asm //声名内联汇编代码 { MRS tmp, CPSR BIC tmp, tmp, #0x80 MSR CPSR_c, tmp }}
汇编语句块中,如果有两条指令占据了同一行,那么必须用分号“ ;”将它们分隔
如果一条指令需要占用多行,那么必须用反斜线符号“ \ ”作为续行符
可以在内联汇编语言块内的任意位置使用C/C++格式的注释
内联汇编代码中定义的标号可被用作跳转或C/C++ goto 语句的目标,同样,在C/C++代码中定义的标号,也可被用作内联汇编代码跳转指令的目标
内联汇编的限制
- 它不支持 Thumb 指令;除了程序状态寄存器 PSR 之外,不能直接访问其他任何物理寄存器
- 如果在内联汇编程序指令中出现了以某个寄存器名称命名的操作数,那么它被叫做虚拟寄存器,而不是实际的物理寄存器。编译器在生成和优化代码的过程中,会给每个虚拟寄存器分配实际的物理寄存器,但这个物理寄存器可能与在指令中指定的不同。
- 在内联汇编代码中不能使用寄存器 PC(R15)、LR(R14)和SP(R13)
- 更改处理器模式会禁止使用 C 操作数或对已编译 C 代码的调用,直到将处理器模式恢复为原设置之后
状态寄存器 PSR ,任何对 PSR 的引用总是执行指向物理 PSR
在内联汇编语句块中最好使用 C 或 C++ 变量作为操作数
嵌入式汇编
嵌入式汇编程序是一个编写在C程序外的单独汇编程序,该程序段可以像函数那样被 C 程序调用
嵌入式汇编具有真实汇编的所有特性,数据交换符合 ATPCS 标准,同时支持 ARM 和Thumb,所以它可以对目标处理器进行不受限制的低级访问
不能直接引用 C/C++ 的变量
定义一个嵌入式汇编函数的语法格式为
_ _asm return–type function–name(parameter-list){ 汇编程序段}
- return–type:函数返回值类型,C语言中的数据类型
- function–name:函数名
- parameter-list:函数参数列表
参数名只允许使用在参数列表中,不能用在嵌入式汇编函数体内
在 C 程序中调用嵌入式汇编程序的方法与调用 C 函数的方法相同
内联汇编与嵌入式汇编的差异
内联汇编代码使用高级处理器抽象,并在代码生成过程中与 C 和 C++代码集成。因此编译程序将 C 和 C++代码与汇编代码一起进行优化
嵌入式汇编代码从 C 和 C++ 代码中分离出来单独进行汇编,产生与 C 和 C++ 源代码编译对象相结合的编译对象
可通过编译程序来内联汇编代码,但无论是显示还是隐式,都无法内联嵌入式汇编代码
- C语言与汇编语言之间的函数调用
- C语言与汇编语言的相互调用
- 汇编语言调用C语言函数的简单方法
- 嵌入式汇编语言调用C语言函数的小例子
- C语言与汇编语言相互调用
- 在c语言之中文件的读写和函数与函数之间参数的调用
- [编程语言][汇编语言]另类的函数调用
- C语言调用汇编语言的简单方法
- c语言与汇编语言:
- 【龙芯1c库】龙芯1c上c语言写的函数调用汇编语言写的函数
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈(转载)
- ARM基础:为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- Sql镜像同步卡死的一个案例
- loj6224「网络流 24 题」深海机器人问题(费用流)
- 递归函数
- GridView动态增加行
- 独家 | 一文读懂LinkedIn个性化推荐模型及建模原理
- C语言与汇编语言之间的函数调用
- 清华成立“脑与智能”和“未来”两大实验室,跨学科AI深度融合
- ubuntu17.10安装docker
- COURSE 2 Improving Deep Neural Networks Hyperparameter tuning, Regularization and Optimization
- Java中如何让web服务器启动的时候自动运行web程序中某个类的某个方法
- 010
- 番外7>林芝·救赎之旅的最后一站·上——AI主题科幻小说《地与光》
- 反射中获取私有的对象
- 仿163网盘无刷新多文件上传系统