主要观点:Unix 类操作系统常用fork
系统调用创建新进程,其在用户代码中的工作方式初学时易令人困惑,需通过检查fork
的返回值确定在子进程或父进程中。通过示例代码展示了fork
及execve
的使用,解释了在if
条件分支中同时出现以及fork
如何返回两个不同值等疑惑,还介绍了系统调用的底层实现及相关汇编指令,如movq
、cmpq
、jz
等,并展示了用汇编重写的示例程序及相关解读。
关键信息:
fork
创建子进程,子进程是父进程的副本(有内部差异),系统调用返回后需检查返回值确定进程。- 示例中父进程打印消息后等待子进程结束,子进程执行
ls
程序。 - 系统调用在内核实现,用户空间代码需用特定指令请求内核执行,
libc
提供系统调用包装器。 - X86 架构下系统调用的约定:将系统调用号放入
RAX
寄存器,最多六个参数通过特定寄存器传递,返回值存于RAX
。 - 用汇编重写示例程序,通过
movq
设置寄存器,cmpq
比较值,jz
根据比较结果跳转等。
重要细节:
fork
函数实际是libc
提供的fork
系统调用的包装器。- 不同架构的系统调用调用约定不同,文中还列出了其他架构的相关内容。
- 给出了
exit
系统调用的示例汇编代码及相关注释。 - 完整的汇编程序可在这里找到,运行
make
可构建程序。 - 关键是系统调用的返回值写入
RAX
寄存器,fork
时父进程RAX
为子进程pid
,子进程RAX
为 0。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。