操作系统第一次实验
王晗炜 16281049 计科1601
1. (系统调用实验)了解系统调用不同的封装形式
- 1 阅读分别运行用API接口函数getpid()直接调用和汇编中断调用两种方式调用Linux操作系统的同一个系统调用getpid的程序(请问getpid的系统调用号是多少?linux系统调用的中断向量号是多少?)。
-
调用API接口函数:
源代码
getpid.c
:#include <stdio.h> #include <unistd.h> int main(){ pid_t pid; pid = getpid(); printf("%d\n",pid); return 0; }
在linux系统上编译并运行:
-
调用汇编中断:
源代码
assembly.c
:#include <stdio.h> #include <unistd.h> int main(){ pid_t pid; asm volatile( "mov $0,%%ebx\n\t" "mov $0*14,%%eax\n\t" "int $0*80\n\t" "mov %%eax,%0\n\t" :"=m"(pid) ); printf("%d\n",pid); return 0; }
在linux上编译并运行:
由以上运行结果可知这两种方式都可以顺利获取进程号,其中第一种方式直接调用了linux系统内封装好的getpid()函数,第二种方式选用汇编语言中的软中断方式,调用0×80号中断,在C源文件中嵌入汇编语言完成中断调用。
通过查阅Linux系统中的unistd.h头文件可以找到为getpid设置的系统调用号为172(其查找过程如下)
通过阅读给出的汇编代码我们可以发现其中断向量号之后的功能号并不为172,而是0×14,即20。但程序并没有出现问题,仍成功返回了我们需要的进程号。之后自己上网查阅了相关资料,发现32位和64位的Linux系统中的系统调用号并不相同,并分别存储在unistd_32.h和unistd_64.h头文件中,在32位系统中getpid的系统调用号为20,与我们编写的汇编程序一致,64位系统中的getpid的系统调用号为39。而对于64位的操作系统,基本上已经抛弃了int 80这种老旧的系统调用的方式,取而代之的是syscall这个函数。但如果仍在64位系统中使用int 80这种软中断方式进行系统调用,便还是遵循原先32位系统中的系统调用号,这算是64位系统对之前系统的一种兼容。至此前面的疑问已经能得到解释。
- 2 上机完成习题1.13
-
首先直接使用C语言实现需求:
源代码
hello_linux.c
:#include <stdio.h> int main(){ printf("Hello Linux\n"); return 0; }
在Linux系统中使用gcc编译并执行:
可知得到了对应的结果
-
随后使用汇编语言实现需求:
源代码
hello_linux.asm
:section data string db "Hello Linux" len equ $-msg section .text global _start _start: mov eax,4 mov ebx,1 mov ecx,string mov edx,len int 0x80 mov eax,1 mov ebx,0 int 0x80
可见输出结果正确,汇编调用成功
- 3 阅读pintos操作系统源代码,画出系统调用实现的流程图。