标签:
“平安的祝福 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
API只是一个函数定义;系统调用通过软中断向内核发出一个明确的请求。
Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用):一般每个系统调用对应一个封装例程;库再用这些封装例程定义出给用户的API
-1在多数情况下表示内核不能满足进程的请求;
Libc中定义的errno变量包含特定的出错码;
在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常
内核实现了很多不同的系统调用,进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数,使用eax寄存器
实际的值,用户态进程地址空间的变量的地址,甚至是包含指向用户态函数的指针的数据结构的地址
步骤:1.一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)。这个寄存器的设置是libc库中的封装例程进行的,因此用户一般不关心系统调用号。
2.进入sys_call之后,立即将eax的值压入内核堆栈。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("The current process ID is %d\n",getpid());
return 0;
}
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int t;
asm volatile(
"mov $0,%%ebx\n\t"
"mov $0x14,%%eax\n\t" //其中getpid的系统调用数是20
"int $0x80\n\t"
"mov %%eax,%0"
:"=m"(t)
);
printf("The current process ID is %d\n",t);
return 0;
}
首先将ebx寄存器清空,将getpid的系统调用号传入寄存器eax,然后调用系统软中断。系统中断处理完成后,eax寄存器存储的是系统调用getpid的返回值,将eax寄存器的值赋值给用户空间的参数。
通过这次实验,大致了解用户程序如何执行系统调用的。流程:用户程序调用API——》封装例程——》中断向量实现系统程序的切换——》系统调用具体的汇编程序。
标签:
原文地址:http://www.cnblogs.com/pingandezhufu/p/4373142.html