2021-2022-1 20212822《Linux内核原理与分析》第五周作业
实验四:使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用
-
实验要求
- 选择一个系统调用(13 号系统调用 time 除外),系统调用列表参见 torvalds/linux
- 参考视频中的方式使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用
-
实验基础知识
-
实验过程
#include<stdio.h>
int main(){
int ret;
char *oldname = "myrename.c";
char *newname = "20212822_myrename.c"
ret = rename(oldname, newname);
if(!ret)
printf("Renamed successfully!\n");
else
printf("Unable to rename the file!\n");
return 0;
}
#include<stdio.h>
int main(){
int ret;
char *oldname = "myrename.c";
char *newname = "20212822_myrename.c";
asm volatile(
"movl %2,%%ecx\n\t"
"movl %1,%%ebx\n\t"
"movl $0x26,%%eax\n\t"
"int $0x80\n\t"
"movl %%eax,%0"
:"=m"(ret)
:"b"(oldname),"c"(newname)
);
if(!ret)
printf("Renamed successfully!\n");
else
printf("Unable to rename the file!\n");
return 0;
}
-
接着用gcc编译该代码运行尝试,结果如下图所示:
-
以上使用的C代码内嵌汇编方式
-
对实验过程的理解
- 本次实验较为容易,过程中没有发生代码无法编译运行的情况。下面谈一谈对rename系统调用过程的理解:
- 有两个参数oldname和newname,oldname是第一个传给EBX寄存器的参数,newname是第二个传给ECX寄存器的参数,因为参数是字符串,所以实际传递的是指针变量。把系统调用号38(16进制是0x26)存入EAX寄存器,将oldname存入EBX寄存器,将newname存入ECX寄存器,通过执行int $0x80来执行系统调用陷入内核态。system_call根据传入的系统调用号在系统调用列表中查找到对应的系统调用内核函数,然后根据EBX寄存器和ECX寄存器中保存的参数调用用内核函数sys_rename,执行完成后将执行结果存放到EAX寄存器中,将EAX寄存器的值传给ret。以上为rename系统调用在C语言中内嵌汇编代码的过程