使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
2015-03-29 09:44
531 查看
林万喜 原创作品 转载请注明出处 USTC 2015.3
《Linux内核分析》MOOC课程:在线课程链接http://mooc.study.163.com/course/USTC-1000029000
Linux系统调用是Linux内核为我们提供的一些访问硬件的接口,为我们使用和访问硬件提供了方便。如我们平常使用的rm,mkdir,touch等处理硬盘上文件的命令,其实现过程中都要用到对应的系统调用。但是作为普通用户的我们运行的程序只能运行在用户空间,并不能直接调用处于系统内核态的系统调用,所以系统给我们封装了对应的API[Application
Program Interface]来让用户程序可以使用系统调用。下面简单说明系统调用实现过程:
应用程序调用相关API
API将对应的系统调用号存入eax,如果需要传参,还要在其他寄存器中传入相关参数,然后调用int $0x80触发中断进入内核中的中断处理函数
内核中的中断处理程序根据系统调用号调用对应的系统调用
系统完成相应功能,将返回值存入eax,返回到中断处理函数
[根据视频中的描述,这里是一个进程调度时机,所以可能会发生进程调度]
中断处理函数返回到API中
API将eax,即系统调用的返回值返回给应用程序
使用库函数调用 API。
[cpp] view
plaincopy
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t fpid;//fpid表示 fork 函数返回的值
fpid = fork();
if(fpid < 0)
printf("error in fork!\n");
else if (fpid == 0)
printf("I am the child process,my process id is %d\n",getpid());
else
printf("I am the parent process, my process id is %d\n",getpid());
return 0;
}
调用 fork()后,返回一个 fpid 的值,根据 fpid 的值来判断是父进程还是子进程,或者是库函数 API调用错误。
下面是 C 语言中嵌入汇编代码调用库函数 fork()函数
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pid_t _fork_asm_()
{
pid_t tt;
asm volatile(
"mov $0x2, %%eax\n\t"
"int $0x80\n\t"
"mov %%eax, %0\n\t"
:"=m" (tt)
);
return tt;
}
int main(int argc, const char *argv[])
{
pid_t tt;
tt = _fork_asm_();
if (tt == 0)
{
printf("I am the child process,my pid is %d\n",getpid());
}
else
{
printf("I am the parent process,my pid is %d\n",getpid());
}
return 0;
}
由于没有参数传入,在嵌入汇编代码时,直接调用
[cpp] view
plaincopy
mov $0x2, %%eax
由于 fork 函数在 i386机器中为2号系统调用,所有直接调用2号进程。
[cpp] view
plaincopy
int $0x80
系统调用函数结束会产生80号系统中断来还原系统调用之前的现场,程序继续往下执行。
[cpp] view
plaincopy
mov %%eax, %0
返回值存储到 eax 中。
执行结果如图
总结:
参数传递过程:可以看出来这个实验只需要使用eax传递系统调用编号,然后使用eax接受返回值,最后进行写入内存。
系统调用分析:
用户设置参数,调用中断,保护现场。
中断向量表,进行系统调用,进入内核态
内核处理,返回参数
返回参数,恢复现场。
《Linux内核分析》MOOC课程:在线课程链接http://mooc.study.163.com/course/USTC-1000029000
Linux系统调用是Linux内核为我们提供的一些访问硬件的接口,为我们使用和访问硬件提供了方便。如我们平常使用的rm,mkdir,touch等处理硬盘上文件的命令,其实现过程中都要用到对应的系统调用。但是作为普通用户的我们运行的程序只能运行在用户空间,并不能直接调用处于系统内核态的系统调用,所以系统给我们封装了对应的API[Application
Program Interface]来让用户程序可以使用系统调用。下面简单说明系统调用实现过程:
应用程序调用相关API
API将对应的系统调用号存入eax,如果需要传参,还要在其他寄存器中传入相关参数,然后调用int $0x80触发中断进入内核中的中断处理函数
内核中的中断处理程序根据系统调用号调用对应的系统调用
系统完成相应功能,将返回值存入eax,返回到中断处理函数
[根据视频中的描述,这里是一个进程调度时机,所以可能会发生进程调度]
中断处理函数返回到API中
API将eax,即系统调用的返回值返回给应用程序
使用库函数调用 API。
[cpp] view
plaincopy
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t fpid;//fpid表示 fork 函数返回的值
fpid = fork();
if(fpid < 0)
printf("error in fork!\n");
else if (fpid == 0)
printf("I am the child process,my process id is %d\n",getpid());
else
printf("I am the parent process, my process id is %d\n",getpid());
return 0;
}
调用 fork()后,返回一个 fpid 的值,根据 fpid 的值来判断是父进程还是子进程,或者是库函数 API调用错误。
下面是 C 语言中嵌入汇编代码调用库函数 fork()函数
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
pid_t _fork_asm_()
{
pid_t tt;
asm volatile(
"mov $0x2, %%eax\n\t"
"int $0x80\n\t"
"mov %%eax, %0\n\t"
:"=m" (tt)
);
return tt;
}
int main(int argc, const char *argv[])
{
pid_t tt;
tt = _fork_asm_();
if (tt == 0)
{
printf("I am the child process,my pid is %d\n",getpid());
}
else
{
printf("I am the parent process,my pid is %d\n",getpid());
}
return 0;
}
由于没有参数传入,在嵌入汇编代码时,直接调用
[cpp] view
plaincopy
mov $0x2, %%eax
2 i386 fork sys_fork stub32_fork
由于 fork 函数在 i386机器中为2号系统调用,所有直接调用2号进程。
[cpp] view
plaincopy
int $0x80
系统调用函数结束会产生80号系统中断来还原系统调用之前的现场,程序继续往下执行。
[cpp] view
plaincopy
mov %%eax, %0
返回值存储到 eax 中。
执行结果如图
总结:
参数传递过程:可以看出来这个实验只需要使用eax传递系统调用编号,然后使用eax接受返回值,最后进行写入内存。
系统调用分析:
用户设置参数,调用中断,保护现场。
中断向量表,进行系统调用,进入内核态
内核处理,返回参数
返回参数,恢复现场。
相关文章推荐
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(Linux)
- 实验--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用(李鹏举)
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用----20135334赵阳林
- 实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 20135239 益西拉姆 linux内核分析 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- linux内核分析第四周-使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 《Linux操作系统分析》之使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 实验四——使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用