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

Linux下用C語言調用GAS匯編——綜合實例

緊接上一篇 http://www.linuxidc.com/Linux/2014-11/108832.htm,上篇寫的是用GAS匯編調用C語言,這次講用C語言調用GAS匯編。在內核編寫中主要用的是前者,但是在日常程序優化中,主要用的是後者。

    還是同樣的功能,實現兩個數值的交換,把參數從C語言傳遞進匯編,再用C語言接收從匯編函數返回的返回值,返回值又分為普通整數返回值和字符串返回值。

    建立三個文件,分別為main.c、retstr.s、swapint.s。其中main.c是C語言文件,也就是主函數所在,swapint.s是匯編函數,用於交換兩個變量數值並返回一個整數值給C語言函數,retstr.s也是匯編語言函數,用於演示匯編語言輸出屏幕提示,采用了直接寫入stdout和調用C庫兩種方式,之後返回一個字符串給C語言函數。

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

main.c的代碼如下

#include<stdio.h>
char *retstr();    #C程序默認函數返回值為整數值,這裡要聲明下,應該是字符串指針。
int main()
{
    int a;
    int b;
    int c;
    char *str;
    a=10;
    b=20;
    c=swapint(&a,&b);
    printf("The 'swapint' return:%d\n",c);
    printf("Now:a=%d;b=%d\n",a,b);
    str=retstr();
    printf("The 'retstr' return:%s",str);
    return 0;
}

swapint.s的代碼如下:

.section .text
.globl swapint
.type swapint,@function
swapint:
    pushl %ebp
    movl %esp,%ebp
    pushl %ebx
    movl 8(%ebp),%esi
    movl 12(%ebp),%edi
    movl (%esi),%ebx
    xchg %ebx,(%edi)
    movl %ebx,(%esi)
    movl $2333,%eax
    popl %ebx
    movl %ebp,%esp
    popl %ebp
    ret 

retstr.s的代碼如下:

.section .data
msg:
    .asciz "Use syscall:The value has been swapped!\n"
msgend:
    .equ len,msgend-msg
msg2:
    .asciz "Call 'printf' successfully!\n"
retvalue:
    .asciz "It's ok!\n"
.section .text
.globl retstr
.type retstr,@function
retstr:
    pushl %ebp
    movl %esp,%ebp
    pushl %ebx
    #using system call
    movl $4,%eax  #the number of syscall
    movl $1,%ebx  #fd
    movl $msg,%ecx #the pointer of msg
    movl $len,%edx #the length
    int  $0x80        #call "write"
    #using C library
    pushl $msg2
    call printf
    #return a string
    movl $retvalue,%eax
    #leave
    popl %ebx
    movl %ebp,%esp
    popl %ebp
    ret

    寫個腳本debug-auto.sh自動編譯這些文件,同時附帶調試信息,方便GDB調試。

as -o swapint.o swapint.s -gstabs
as -o retstr.o retstr.s -gstabs
gcc -o a.out swapint.o retstr.o main.c -gstabs

    之後就是編譯運行,結果如下:

    這就是在C語言中綜合調用GAS匯編函數。

    有問題歡迎討論。

Copyright © Linux教程網 All Rights Reserved