程序如何使用系统调用?

我们自己写的程序,如何使用系统调用?在编译时,如何将系统调用表示?

我猜测,我们的程序编译为二级制代码时,先对一些寄存器进行设置,然后跳入到int ox80中断,这样自然就进入到函数调用中去了。

但是,为什么我们可以直接引用那些包含系统调用的头文件,然后直接使用系统调用? 因为系统调用函数里面,实现了我上面所说的过程。
那这样的话,这个实现过程被包装成了什么? 动态库?
例如系统调用函数头文件<linux/unistd.h>,它对应的库是什么?是不是就是kernel呢? kernel不是库吧?经查找资料发现如下:

一个直接系统调用的例子:

#include <syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int main(void) {
long ID1, ID2;
/*-----------------------------*/
/* 直接系统调用*/
/* SYS_getpid (func no. is 20) */
/*-----------------------------*/
ID1 = syscall(SYS_getpid);
printf ("syscall(SYS_getpid)=%ld\n", ID1);
/*-----------------------------*/
/* 使用"libc"封装的系统调用 */
/* SYS_getpid (Func No. is 20) */
/*-----------------------------*/
ID2 = getpid();
printf ("getpid()=%ld\n", ID2);
return(0);
}

linux0.01中, unistd.h头文件中有上面这个例子中系统调用 syscall 的实现为:

#define _syscall0(type,name) \
type name(void) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name)); \
if (__res >= 0) \
    return __res; \
errno = -__res; \
return -1; \
}

#define _syscall1(type,name,atype,a) \
type name(atype a) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name),"b" (a)); \
if (__res >= 0) \
    return __res; \
errno = -__res; \
return -1; \
}

#define _syscall2(type,name,atype,a,btype,b) \
type name(atype a,btype b) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name),"b" (a),"c" (b)); \
if (__res >= 0) \
    return __res; \
errno = -__res; \
return -1; \
}

#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
type name(atype a,btype b,ctype c) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name),"b" (a),"c" (b),"d" (c)); \
if (__res<0) \
    errno=-__res , __res = -1; \
return __res;\
}

明白了,系统调用就在unistd.h头文件中实现了。

下面是另一个例子,更直接一点:C代码:

1 int main()
2 {
3 write(1, "hello, world\n", 13);
4 exit(0);
5 }

编译后汇编代码:

1 .section .data
2 string:
3 .ascii "hello, world\n"
4 string_end:
5 .equ len, string_end - string
6 .section .text
7 .globl main
8 main:
First, call write(1, "hello, world\n", 13)
9 movl $4, %eax System call number 4
10 movl $1, %ebx stdout has descriptor 1
11 movl $string, %ecx Hello world string
12 movl $len, %edx String length
13 int $0x80 System call code
Next, call exit(0)
14 movl $1, %eax System call number 0
15 movl $0, %ebx Argument is 0
16 int $0x80 System call code



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值