扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:chinaunix 来源:chinaunix 2007年11月2日
关键字: Linux
系统控制权就会转向真正的系统调用, 用来完成你的请求并返回。 然后_system_call()调用_ret_from_sys_call()来检查不同的返回值, 并且最后返回到用户内存。
* libc
这int $0x80 并不是直接被用作系统调用; 更确切地是, libc函数,经常用来包装0x80中断,这样使用的。
libc通常利用_syscallX()宏来描述系统调用, X是系统调用的总参数个数。
举个例子吧, libc中的write(2)就是利用_syscall3这个系统调用宏来实现的, 因为实际的write(2)原型需要3个参数。在调用0x80中断之前,这个_syscallX宏假定系统调用的堆栈结构和要求的参数列表,最后,当_system_call()(通过int &0x80来引发)返回的时候,_syscallX()宏将会查出错误的返回值(在%eax)并且为其设置errno。
让我们看一下另一个write(2)例程并看看它是如何进行预处理的。
[root@plaguez kernel]# cat no2.c
#include #include #include #include #include #include #include #include #include _syscall3(ssize_t,write,int,fd,const void *,buf,size_t,count);/*构建一个write调用*/
main()
{
char *t = "this is a test.n";
write(0, t, strlen(t));
}
[root@plaguez kernel]# gcc -E no2.c > no2.C
[root@plaguez kernel]# indent no2.C -kr
indent:no2.C:3304: Warning: old style assignment ambiguity in "=-". Assuming "= -"
[root@plaguez kernel]# tail -n 50 no2.C
#9 "no2.c" 2
ssize_t write(int fd, const void *buf, size_t count)
{
long __res;
__asm__ __volatile("int $0x80":"=a"(__res):"0"(4), "b"((long) (fd)), "c"((long) (buf)), "d"((long) (count)));
if (__res >= 0)
return (ssize_t) __res;
errno = -__res;
return -1;
};
main()
{
char *t = "this is a test.n";
write(0, t, strlen(t));
}
[root@plaguez kernel]# exit
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。