其他分享
首页 > 其他分享> > 操作系统(2)应用眼中的操作系统:系统调用

操作系统(2)应用眼中的操作系统:系统调用

作者:互联网

操作系统(2)应用眼中的操作系统:系统调用

什么是(应用)程序

image-20210313145157174

ELF二进制文件

image-20210313145327968

解析ELF文件

如何解析

readelf是专门解析EIF可执行文件的工具;我们需要关注:

在c程序中引入elf.h,/usr/include/elf.h提供了必要的定义

image-20210313151009381

readelf使用说明

image-20210313151209147

Hello World眼中的操作系统

如何实现一个最简单的c语言程序?跟着大佬做出的尝试

失败的尝试1

如下图,这是一个简单的helloworld程序:

image-20210313152957670

我们尝试进行编译:

image-20210313153138990

一个c语言经历的过程:.c -> 预处理 -> .l -> 编译 -> .s -> 汇编 -> .o -> 链接 -> .out

从上面我们可以看出,该程序在链接时出现两处错误,大佬的解释(其实还有点懵,希望后面的学习能彻底懂):

image-20210313153800705

失败的尝试2

做出修改后:

image-20210313154036678

再次进行编译链接:

image-20210313154143632

此时只出现了一处错误,为什么?还是连接器入口的问题,那我们指定一下入口,说不定可以?

image-20210313154428335

终于链接成功了,但是又…运行失败!!!为什么。。。。

此时大佬带我们学习一个编译工具gdb。这样可以观察程序的执行!

常用的命令如下(后续我会学习一下gdb手册,专门写一篇博客介绍):

image-20210313154733296

那么开始调试这个程序:

image-20210313155445036

image-20210313155602736

image-20210313155742162

image-20210313155946724

image-20210313160231156

从上图的调试中可以看到,return那里很奇怪,return指令是从栈上弹出返回的地址,和return配对的是call指令,当有一条call指令时,会把返回值放在堆栈上,然后跳转到main执行。而main函数又是谁调用的呢?真相只有一个,那就是操作系统帮我们加载了main

所以继续执行会出现非法的地址访问这个错误

操作系统做了什么?

成功的尝试——汇编语言

image-20210313161625975

大佬的汇编语言版本(学完汇编一定亲自试一下):

image-20210313162518564

整个运行过程的梳理:前面四条设置参数,然后syscall调用系统API,然后应用程序进入操作系统,执行很多指令,直到调用I/O输出hello,os world;最后三条指令是退出程序,设置返回值什么的。

image-20210313163921640

C语言版本:

image-20210313162220772

运行:

image-20210313164216066

image-20210313164411719

image-20210313164714309

结果:

image-20210313164837131

main()之前发生了什么?

image-20210313164955822

调试程序:

image-20210313165952567

image-20210313170040643

image-20210313170206164

image-20210313170359722

可以看到,系统帮我们加载了a.out的程序,然后再加载了ld-2.27.so初始的加载器。ld-2.27.so会帮我们加载libc,然后再调用libc初始化,最后调用main。

所以,main()开始之前:

image-20210313170915894

main执行之前,发生了哪些API的调用?使用trace工具

image-20210313171117003

一个练习的小demo:

image-20210313172431440

image-20210313172746698

可以看到,第一个系统调用是加载a.out,然后后面的系统调用都是加载器和libc调用的

关于libc的简单介绍:

image-20210313172945913

查看后半段的调用:

image-20210313173044425

可以看到,执行第一个write的之后就调用I/O,在终端输出helloworld,这是分时系统的一个体现

image-20210313173526672

应用眼中的操作系统

本质上,所有的程序都和hello world类似

image-20210313173722657

这些都是后面会学到的系统调用API。

demo:gcc

image-20210313173836449

打印出了很长的系统调用序列

image-20210313174159412

image-20210313174423564

主要的系统调用都在上面可以看到,包括cc1,as,collect2,ld

image-20210313174834409

各式各样的应用程序都是在这一套API上构建的!

image-20210313175023195

标签:调用,操作系统,查看,程序,眼中,out,加载
来源: https://blog.csdn.net/weixin_45834777/article/details/114755427