紧接上一篇博文,上篇写的是用GAS汇编调用C语言,这次讲用C语言调用GAS汇编。在内核编写中主要用的是前者,但是在日常程序优化中,主要用的是后者。
还是同样的功能,实现两个数值的交换,把参数从C语言传递进汇编,再用C语言接收从汇编函数返回的返回值,返回值又分为普通整数返回值和字符串返回值。
建立三个文件,分别为main.c、retstr.s、swapint.s。其中main.c是C语言文件,也就是主函数所在,swapint.s是汇编函数,用于交换两个变量数值并返回一个整数值给C语言函数,retstr.s也是汇编语言函数,用于演示汇编语言输出屏幕提示,采用了直接写入stdout和调用C库两种方式,之后返回一个字符串给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汇编函数。
有问题欢迎讨论。
本文出自 “mirage1993” 博客,请务必保留此出处http://mirage1993.blog.51cto.com/2709744/1560680
原文地址:http://mirage1993.blog.51cto.com/2709744/1560680