Appearance
概念
- 要实现 C 和汇编的混合编程必须遵守 ATPCS 规范
- ATPCS:ARM-Thumb Procedure Call Standard
c
int add(int i, int j)
{
return i + j;
}- 函数参数的传递采用
r0-r3进行传递,如果参数的个数大于 4 个通过压栈的方式进行传递 - 函数的返回值通过
r0返回,如果函数的返回值大于 4 个字节通过r0-r1返回 - ATPCS 规范中规定 ARM 采用满减栈
汇编调用 C 函数
asm
.text
.global _start
_start:
@ 1. 初始化栈指针,C代码运行必须有栈
ldr sp, =0x40000820
@ 2. 汇编调用c函数
@ 2.1 给C的函数传递实参值
mov r0, #3 @ a = 3
mov r1, #4 @ b = 4
mov r2, #5 @ c = 5
mov r3, #6 @ d = 6
@ 2.2 汇编调用c的函数
bl add_func
@ 2.3 函数的返回通过r0返回,查看r0寄存器中的值
loop:
b loop
.endc
int add_func(int a, int b, int c, int d) {
return (a + b + c + d);
}C 调用汇编标签
asm
/* 起始汇编文件 */
.text
.globl _start
_start:
@ 1. 初始化栈指针,C代码运行必须有栈
ldr sp, =0x40000820
@ 2. 汇编调用c,跳转到main函数
b main
.endc
// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);
int sum = 0;
int main() {
// 在c代码中调用汇编代码
sum = add_func(1,2,3,4);
while(1);
return 0;
}asm
.text
.global add_func @ 将add_func函数声明为全局
add_func:
add r0, r0, r1
add r0, r0, r2
add r0, r0, r3
mov pc, lr
.end内联汇编
内联汇编的格式:
c
asm volatile(
"汇编指令\n\t"
......
:输出列表
:输出列表
:破坏列表
); // 破坏列表指定我们当前可用的寄存器c
// 内联汇编
int add_func2(int a, int b, int c, int d) {
int sum = 0;
// 使用汇编实现求和
asm volatile(
"add r0, r0, r1\n\t"
"add r0, r0, r2\n\t"
"add r0, r0, r3\n\t"
:"=r"(sum)
:"r"(a),"r"(b),"r"(c),"r"(d)
:"memory" );
return sum;
}
//"=r"(sum)表示输出从寄存器中放到变量sum中
// "r"(a) 指定输入从变量a中获取放到通用寄存器
//"memory"声明使用内存
// 使用extern对函数进行声明
extern int add_func(int a, int b, int c, int d);
int sum = 0;
int main() {
// 调用内联汇编的函数
sum = add_func2(5,6,7,8);
// 在c代码中调用汇编代码
sum = add_func(1,2,3,4);
while(1);
return 0;
}