使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用
系统调用列表参见linux/arch/x86/syscalls/syscall_32.tbl at v3.18-rc6 · torvalds/linux · GitHub,在本实验,选择了20号系统调用getpid来实现直接调用库函数API。
在下面的实验中,将演示如何使用库函数 API 和内嵌汇编代码两种方式来执行相同的系统调用(例如 getpid
)并获得相同的结果,即进程的 PID。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid_lib, pid_asm;
// 使用库函数 API 执行 getpid 系统调用
pid_lib = getpid();
// 使用内嵌汇编代码执行 getpid 系统调用
asm volatile("mov $20, %%eax\n\t" // syscall number for getpid (20)
"syscall\n\t"
"mov %%eax, %0\n\t"
: "=r" (pid_asm) :: "%eax");
printf("Using Library Function (getpid): PID = %d\n", pid_lib);
printf("Using Inline Assembly: PID = %d\n", pid_asm);
return 0;
}
总结
系统调用是用户态进程访问硬件的一种方式,它通过中断(int 0x80)由用户态进入内核态。当一个用户态程序进行系统调用的时候,CPU进入内核态并执行内核函数。
在这个实验中,我们学习了如何使用两种不同的方法(库函数 API 和内嵌汇编代码)来执行相同的系统调用 getpid
以获取进程的 PID。这个实验帮助我们了解了两种方法的异同以及如何在C代码中与汇编代码相互配合。
-
使用库函数 API:我们首先使用了库函数
getpid()
来获取进程的 PID。这是一种简单、便捷的方式,通过标准C库提供的函数调用,我们可以轻松地获得进程的 PID。 -
使用内嵌汇编代码:然后,我们通过内嵌汇编代码执行了相同的
getpid
系统调用。这种方法要求我们使用汇编指令来设置系统调用号、执行系统调用以及获取结果。内嵌汇编为我们提供了更细粒度的控制和更高级别的灵活性。
两种方法都能成功地获取进程的 PID,结果是相同的。但需要注意的是,使用内嵌汇编代码需要更多的代码和对底层系统调用的了解,而使用库函数则更加高级和易于使用。