春宵一刻值千金
花有清香月有阴
很多的资料都会把 read/fork/mmap
等函数称之为系统调用,经过一番了解后,我发现这种叫法应该算是广义的系统调用,也就说这些函数实际上不是真的系统调用。
一般我们在C/C++代码中调用的 read/fork/mmap
等函数其实只是libc/glibc
提供的封装函数,这些函数的实现在 libc.so
里。狭义上的系统调用应该是经过软中断以后,陷入内核态以后才被调用的。
随便给个图就理解了:
可以看到在把系统调用号传入 eax
寄存器后,再通过 syscall
指令陷入内核态。
系统调用的过程
这应该是面试常问的,也算是我一直想要了解一下的。
其实面试的很多知识和实际其实是有一些差距的,比如说函数调用约定中的参数入栈,x64都是按fastcall使用寄存器传参;再比如进程的内存布局中,一般我们会说代码段,数据段在低地址。。。其实在GCC 6.3以上,代码段和数据段都是高地址了。。。
第一行就是代码段的映射,不过还是比堆栈地址要低。