歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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的代碼:

#include<stdio.h>
 
 static int i = 0;
 
 
 void c_add(int *k)
 {
     (*k)++;
 }
 
 int main(void)
 {   
     a_add(&i);
     printf("%d\n",i);
 
     return 0;
 }

assembly.s的代碼:

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

運行結果:

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

Copyright © Linux教程網 All Rights Reserved