Linux下用C语言调用GAS汇编――综合实例

    紧接上一篇博文,上篇写的是用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

    之后就是编译运行,结果如下:

wKiom1QwwYixh5bQAARP3o5_N-E807.jpg

    这就是在C语言中综合调用GAS汇编函数。

    有问题欢迎讨论。


你可能感兴趣的:(linux,汇编,C语言,调用,gas)