首先我们先写一个最最简单的程序,helloworld?no,no,helloworld远远比我们自己看到的要复杂的多。
最最简单的程序应该是这样的
- /*kong.c 源码*/
- int main(void)
- {
- }
接下来,静态编译,strace跟踪查看程序的执行情况。
- leon@leon-virtual-machine:~/Desktop/hello$ gcc kong.c -o kong -static//静态编译
- leon@leon-virtual-machine:~/Desktop/hello$ strace ./kong //跟踪执行
- execve("./kong", ["./kong"], [/* 40 vars */]) = 0 //系统调用:运行可执行文件
- uname({sys="Linux", node="leon-virtual-machine", ...}) = 0//系统调用:获取当前UNIX系统的名称,版本,主机信息等
- brk(0) = 0x8baf000 //系统调用:改变数据段空间的分配,修改堆的大小
- brk(0x8bafd40) = 0x8bafd40//
- set_thread_area({entry_number:-1 -> 6, base_addr:0x8baf840, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0//在当前进程的LTS中设置一个入口
- brk(0x8bd0d40) = 0x8bd0d40//
- brk(0x8bd1000) = 0x8bd1000//
- exit_group(-1081249620) = ? //退出在一个进程里的所有线程
如上所示,空程序在执行过程中execve,uname,brk,set_thread_area,exit_group等系统调用
那么在这些系统调用中,那些是系统本身执行的,那些是程序执行的??
程序源码本身没有任何系统调用,但是在静态编译中,一些库被编译进来,库在程序执行过程中会不会发生系统调用???
库在程序运行过程中,是由程序本身调用的,既然空程序中不存在调用库的代码,那么可以理解为库在执行过程不会产生系统调用
所以也就是说这些系统调用不是由程序调用产生,都是由系统本身执行的。
通过分析这些系统调用,这些系统调用完成了应用程序运行环境的初始化,程序退出返回的功能。
再来看看另外一个应用程序helloworld的运行过程。
- *hello.c 源码*/
- #include <stdio.h>
- int main(void)
- {
- printf("hello, FriendlyARM!\n");
- }
- /***********************************************/
- leon@leon-virtual-machine:~/Desktop/hello$ gcc hello.c -o hello -static //静态编译
- leon@leon-virtual-machine:~/Desktop/hello$ strace ./hello //跟踪执行
- execve("./hello", ["./hello"], [/* 40 vars */]) = 0
- uname({sys="Linux", node="leon-virtual-machine", ...}) = 0
- brk(0) = 0x9336000
- brk(0x9336d40) = 0x9336d40
- set_thread_area({entry_number:-1 -> 6, base_addr:0x9336840, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
- brk(0x9357d40) = 0x9357d40
- brk(0x9358000) = 0x9358000
- fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 //获取文件属性
- mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77c3000 //映射文件或设备到内存
- write(1, "hello, FriendlyARM!\n", 20hello, FriendlyARM![/color][color=#ff0000]) = 20 // 写文件,这里才是helloworld程序本身的操作
- exit_group(20) = ?
除了fstat64,mmap2,write三个系统调用外,其他系统调用都和空程序的执行过程完全一样。
很明显,这三个系统调用就是程序本身的调用执行过程。