ATPCS协议(ARM/Thumb Procedure Call Standard):它规定了一些子程序间调用的基本规则,如子程序调用过程当中的寄存器、堆栈的使用规则,参数的传递规则等。编程
R0~R3:函数调用时传递函数参数,如int add(int a, int b, int c)参数分别对应R0=a,R1=b, R2=c。函数
R0:保存函数的返回值。oop
栈传参:当函数参数超过4个时,多出来的参数利用栈来传递(一次从右往左压栈)。spa
C内嵌汇编:code
注意事项:内嵌汇编中不能直接向PC寄存器赋值。
内嵌汇编指令中不要将R十二、R1三、R1四、R0~R3指定为指令中的物理寄存器,由于这些寄存器可能会存放中间结果或用于子程序调用;一般,内嵌汇编指令中不要指定物理寄存器。
内嵌汇编中,常量前面的“#”能够省略。
C程序中的标号能够被内嵌汇编指令使用,但指令BL不能使用C的标号(指令B则能够)。
编译C内嵌的汇编代码使用的是内嵌汇编器,与armasm汇编器有一些差别。blog
在C程序中嵌入汇编程序,能够实现一些高级语言没有的功能,提升程序的执行效率;可是嵌入的汇编程序不具有可移植性。string
内嵌汇编的语法:
__asm
{
指令[;指令] /*注释*/
...
[指令]
}io
demo:asm
#include <stdio.h> int main(void) { const char *src = "Hello world!"; const char *p = src; char a[20]; char *dst = a; char *dst_print =dst; int ch; __asm { loop: LDRB ch, [src], #1 STRB ch, [dst], #1 CMP ch, #0 BNE loop } printf("Original string:%s\n", p); printf("Copied string:%s\n", dst_print); return 0; }
汇编调用C:编译
.s的汇编文件
AREA Example1,CODE,READONLY ;声明代码段Example1 CODE32 ;声明32位ARM指令 ENTRY IMPORT g ;IMPORT汇编文件中声明引用C函数名 IMPORT global START MOV R0, #1 MOV R2, #2 MOV R3, #3 LDR R7, =global ;将global的地址给到R7 LDR R3, [R7] BL g MOV R8, R0 B START END
.c文件
int global = 10; int g(int a, int b, int c, int d) { return a+b+c+d; }
C调用汇编
.s汇编文件
AREA Example2,CODE,READONLY CODE32 EXPORT strcopy ;EXPORT对外声明汇编中的函数,表示其可被调用 strcopy LDRB R2, [R1], #1 STRB R2, [R0], #1 CMP R2, #0 BNE strcopy MOV PC, LR END
.c文件
#include <stdio.h> extern void strcopy(char*d, char *s); int main(void) { char *srcstr = "First string - source"; char dststr[] = "Second string - destination"; printf("Before copying:\n"); printf("%s %s\n", srcstr, dststr); strcopy(dststr, srcstr); printf("After copying:\n"); printf("%s\n %s\n", srcstr, dststr); return (0); }