Linux匯編與C互相調用


一. 概述

          匯編通過call指令調用C函數,call指令主要有兩個功能:1.將下一條指令的地址保存在棧頂;2.設置eip指向被調用程序代碼的開始處。匯編使用ret指令返回,ret的功能是把返回地址從桟里彈出,並轉到該地址去執行。

        匯編程序調用C函數時,函數的入口參數使用堆棧來傳送。

        C函數調用時,輸入參數采用堆棧方式傳遞,參數的傳遞順序是從右到左,調用者負責清除參數占用的堆棧空間。

        C函數的返回值如果是32位整數則存在eax寄存器,如果是64位整數,則存在edx:eax寄存器。

 

二. 實現

       下面的程序由2個文件組成,一個是assembly.s,另外一個是gnuc.c。程序的功能是:在gnuc.c里定義一個全局變量i,在main()函數里調用assembly.s文件里的a_add()函數,將變量i的地址作為參數傳進去,在a_add()函數里將變量i的值加1,然后調用gnuc.c文件里的c_add()函數,參數也是變量i的地址,在c_add()函數里將參數所指的值加1,最后main()里打印變量i的值。

gnuc.c的代碼:

 1 #include<stdio.h>
 2 
 3 static int i = 0;
 4 
 5 
 6 void c_add(int *k)
 7 {
 8     (*k)++;
 9 } 
10 
11 int main(void)
12 {    
13     a_add(&i);
14     printf("%d\n",i);
15 
16     return 0;
17 }

assembly.s的代碼:

 1 .section .text
 2 .type a_add,@function
 3 .globl a_add
 4 a_add:
 5     pushl %ebp        #現場保護
 6     movl %esp,%ebp
 7 
 8     movl 8(%ebp),%eax #取得C函數傳過來的參數
 9     pushl %ecx        #保護ecx,用作臨時變量
10     movl (%eax),%ecx  #取得指針所指的內容
11     addl $1,%ecx      #將內容+1
12     movl %ecx,(%eax)  #將內容放回指針所指的地方
13     popl %ecx         #恢復ecx
14     pushl %eax        #壓桟,以便傳參給C函數
15     call c_add        #調用C函數
16 
17     addl $4,%esp      #清理局部變量
18     popl %ebp         #恢復現場
19     ret               #返回

運行結果:

       可見程序輸出2,符合預期效果。


免責聲明!

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



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