5、C和彙編混合編程

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);
}
相關文章
相關標籤/搜索