Skip to content
On this page

ARM汇编_混合编程


标签:ARM32汇编/基础  

概念

  • 要实现 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  
 
.end
c
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
.end
c
// 使用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;
}

Last updated: