ATPCS協議(ARM/Thumb Procedure Call Standard):它規定了一些子程序間調用的基本規則,如子程序調用過程中的寄存器、堆棧的使用規則,參數的傳遞規則等。
R0~R3:函數調用時傳遞函數參數,如int add(int a, int b, int c)參數分別對應R0=a,R1=b, R2=c。
R0:保存函數的返回值。
棧傳參:當函數參數超過4個時,多出來的參數利用棧來傳遞(一次從右往左壓棧)。
C內嵌匯編:
注意事項:內嵌匯編中不能直接向PC寄存器賦值。
內嵌匯編指令中不要將R12、R13、R14、R0~R3指定為指令中的物理寄存器,因為這些寄存器可能會存放中間結果或用於子程序調用;通常,內嵌匯編指令中不要指定物理寄存器。
內嵌匯編中,常量前面的“#”可以省略。
C程序中的標號可以被內嵌匯編指令使用,但指令BL不能使用C的標號(指令B則可以)。
編譯C內嵌的匯編代碼使用的是內嵌匯編器,與armasm匯編器有一些差異。
在C程序中嵌入匯編程序,可以實現一些高級語言沒有的功能,提高程序的執行效率;但是嵌入的匯編程序不具備可移植性。
內嵌匯編的語法:
__asm
{
指令[;指令] /*注釋*/
...
[指令]
}
demo:
#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); }
