C與匯編語言混合編程


一、在Keil上調用使用C語言調用匯編程序

 

在前面的博客中,我們已經熟悉了Keil中創建項目和keil的一些簡單使用,參考鏈接:https://www.cnblogs.com/LinZJ0423/p/15357620.html

構建代碼

tets.s中的代碼:

    AREA My_Function,CODE,READONLY
    EXPORT Init_1
        
        
Init_1
    MOV R1,#666
    MOV R2,#888
    
LOOP
    CMP R1,#10
    BHS LOOP_END
    ADD R2,#1
    ADD R1,#1
    B LOOP
    
LOOP_END
    NOP
    
    END

main.c中的代碼:

#include<stdio.h>

extern void Init_1(void);

int main(){
    
    Init_1();
    
    return 0;
}

 

 

 

 可以看見c語言成功調用匯編程序。

小結

在C語言中調用匯編函數時,需要在.c文件中用extern Return_Type Function_Name(Datatype parameter); 聲明,然后在main函數中調用,在匯編里面用EXPORT Function_Name就可以與.c文件中的函數聯系起來。

二、做些小改動

在這里我們首先要搞清楚在ARM中參數是如何傳遞和使用的。
在X86平台下:

1.C語言調用函數傳遞參數的方法

C語言調用函數時,在32位程序中使用棧傳遞,而在64位程序中,傳遞方式和參數個數有關,當參數個數小於等於6個時,參數會使用寄存器被傳遞,當參數大於6個時,6個寄存器被分配后,會利用棧來傳遞多余的參數,且參數的傳遞都是從右到左壓棧或是存入寄存器。
驗證過程參考:https://blog.csdn.net/m0_55708805/article/details/117388229

2.ARM中寄存器用法:

  • r0-r3 用作傳入函數參數,傳出函數返回值。在子程序調用之間,可以將 r0-r3 用於任何用途。被調用函數在返回之前不必恢復 r0-r3。—如果調用函數需要再次使用 r0-r3 的內容,則它必須保留這些內容。
  • r4-r11 被用來存放函數的局部變量。如果被調用函數使用了這些寄存器,它在返回之前必須恢復這些寄存器的值。r11 是棧幀指針 fp。
  • r12 是內部調用暫時寄存器 ip。它在過程鏈接膠合代碼(例如,交互操作膠合代碼)中用於此角色。在過程調用之間,可以將它用於任何用途。被調用函數在返回之前不必恢復
  • r12。
  • 寄存器 r13 是棧指針 sp。它不能用於任何其它用途。sp 中存放的值在退出被調用函數時必須與進入時的值相同。
  • 寄存器 r14 是鏈接寄存器 lr。如果您保存了返回地址,則可以在調用之間將 r14 用於其它用途,程序返回時要恢復
  • 寄存器 r15 是程序計數器 pc。它不能用於任何其它用途。

利用寄存器傳遞參數時,參數值按順序放在寄存器R0,R1,R2,R3中,當參數大於4個時,超過的參數值利用棧傳遞,函數返回時,若有返回值會利用寄存器R0存儲返回。

3.修改代碼

#include<stdio.h>

extern int Init_1(int x);

int main(){
    
    Init_1(1);
    
    return 0;
}
    AREA My_Function,CODE,READONLY
    EXPORT Init_1
    ENTRY
        
Init_1
    ADD R0,R0,#100
    
    BX LR
    
    END

編譯調試結果如下:

 

 

 

總結:

在該實驗中,我們的Init_1函數調用時有一個參數的傳遞,在main函數中我們調用Init_1函數,給了一個參數1,函數執行完畢時,1+100的16進制數為65,我們對函數執行完畢的期望值為65,而在圖中寄存器R0的值就是65。

三.在匯編函數中調用一個C語言寫的函數

在匯編中調用C語言函數XXX,則加上IMPORT XXX,注意Keil工具不允許匯編語句頂格寫,否則會報錯。

main.c代碼:

#include<stdio.h>
extern int sum(int a,int b);
int sum(int a,int b){
  int c;
    a=100;
    b=100;
    c=a+b;
    return c;
}

test.s代碼:

 AREA MYDATA, DATA
    IMPORT sum
 AREA MYCODE, CODE
    ENTRY
    EXPORT __main

__main

    BL sum
    
    BX LR
    
    END

 

 心得體會

匯編語言和C語言的嵌套編程在實現的過程中有一些難度,其中遇到了許多問題查了博客得以解決。在解決的過程中更加深入的了解和體會到了C語言是如何變成匯編語言的,以及了解了底層的執行過程。同時可以使用Cmake去查看GCC是如何把C語言變成匯編語言的。同時對於C語言是如何傳遞參數和ARM如何使用的過程有了深入了解

參考鏈接

https://blog.csdn.net/m0_55708805/article/details/117388229
https://blog.csdn.net/ZHONGkunjia/article/details/51184489
http://lionwq.spaces.eepw.com.cn/articles/article/item/17475/
https://cloud.tencent.com/developer/article/1593645
https://blog.csdn.net/qq_45659777/article/details/120651310


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM