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

什么是(应用)程序

  • 可执行的文件(程序的二进制代码和数据)和其他数据文件

    • Linux支持多种可执行文件·格式
    • ELF(Executable Linkable Format)最常用
  • 正在运行的称为进程
    • 操作系统中有许多进程对象
    • 在运行时,进程会
      • 在CPU上执行,进行计算
      • 使用操作系统API访问操作系统中的其他对象

  • 系统中常见的应用程序

ELF二进制文件

  • 文件处理常用命令:

    • vi a.c 直接编辑文件。按i进入编辑模式,:q不保存退出,:wq或:x保存并退出
    • file a.o 查看文件的信息。比如是什么格式的文件。
    • cat a.c 查看文件的内容
    • xxd a.o 二进制显示和处理文件工具

解析ELF文件

如何解析

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

  • ELF文件的header(元数据):

    • 文件内容的分布
    • 指令集体系结构
    • 入口地址
  • ELF的header:决定该文件如何被加载器加载(执行)

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

readelf使用说明

  • 使用man readelf可查看使用说明

  • readelf -h a.o查看头部信息

  • readelf -l a.out 显示程序头(段头)信息(如果有数据的话)。

  • readelf -S a.out 显示节头信息(如果有数据的话)

  • readelf -g a.out 显示节组信息(如果有数据的话)

Hello World眼中的操作系统

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

失败的尝试1

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

我们尝试进行编译:

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

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

失败的尝试2

做出修改后:

再次进行编译链接:

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

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

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

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

那么开始调试这个程序:

  • 首先是gdb a.ouy进入调试:

  • 接着是starti,让程序在第一条程序上停下来

  • 接下来是layout asm,可以让我们更加方便地查看汇编代码:

  • 接下来是info register,可以查看所有的寄存器

  • 接下来是单步调试 si,按一次回车键可以单步一次,如图

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

  • 使用bt去打印系统调用栈可以看到main

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

操作系统做了什么?

  • 加载程序,并初始化运行环境(寄存器、代码、数据、堆栈)
  • 从_start开始执行

成功的尝试——汇编语言

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

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

  • man 2 syscall 可以查看系统调用的手册

C语言版本:

运行:

  • 使用objdump:查看目标文件的信息

  • 使用gcc -g 命令编译成二进制代码,再使用objdump -S进行查看

结果:

main()之前发生了什么?

调试程序:

  • 查看寄存器状态:

  • 查看进程状态:info inferiors

  • 查看暂停进程的地址空间的内容: !pmap [pid]

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

所以,main()开始之前:

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

一个练习的小demo:

  • strace ./a.out 追踪api的调用

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

关于libc的简单介绍:

查看后半段的调用:

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

  • 将程序标准输出丢弃: strace ./a.out > /dev/null 输出到这里的内容都会被丢弃,后半段的内容变成了:

应用眼中的操作系统

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

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

demo:gcc

  • strace -f gcc a.c 创建子进程时进行追踪

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

  • strace -f gcc a.c 2>&1 |grep execve 查看 execve系统调用的情况

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

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

操作系统(2)应用眼中的操作系统:系统调用相关推荐

  1. 【代码1】应用眼中的操作系统;系统调用

    这是 bilibili-[完结] 2020 南京大学 "操作系统:设计与实现" (蒋炎岩) 的课程笔记 本节内容概要: - 一个最小的不依赖任何库函数的程序- 经过编译.链接,被操 ...

  2. 一步步编写操作系统 66 浅析c库函数与系统调用1

    本来说好的接下来的工作是要去"丰满"我们的内核,可咱们这种一步一回头的学习方式还得继续啊.其实我了解大家急切写内核的心情,但本书<操作系统真象还原>(请大家支持正版)的 ...

  3. 【操作系统基础】系统接口与系统调用

    本文参考MOOC哈工大操作系统课程与课件 主要基于Linux 0.11系统展开 "Author:Mayiming" 文章目录 一.操作系统接口 1. 什么是操作系统接口? 2. 操 ...

  4. 操作系统_第二章_UNIX操作系统简介

    UNIX 是一个交互式的分时操作系统. UNIX 源代码是开放的. 1 从结构上看,UNIX可以分成内核层和外壳层两部分,如下图所示 2 内核层是UNIX操作系统的核心.它具有存储管理.文件管理.设备 ...

  5. 计算机操作系统期末复习,《计算机操作系统》期末复习课稿.docx

    文档介绍: <计算机操作系统>复****要点第一章操作系统概述 1 .操作系统的定义及特征答: OS 定义: 操作系统是控制和管理计算机硬件和软件资源.合理地组织和管理计算机的工作流程以方 ...

  6. 02326操作系统2017年版-第一章 操作系统概论 知识要点

    一.操作系统的地位和作用(识记) 操作系统是计算机资源的管理者 操作系统通过接口为用户提供各种服务 操作系统是虚拟机和扩展的机器 计算机系统包括硬件和软件两部分,操作系统属于系统软件,是扩充硬件功能, ...

  7. 操作系统4小时速成:操作系统发展和分类,运行环境:运行机制和内核,用户态非特权,核心态特权,中断技术,访管指令

    操作系统4小时速成:操作系统发展和分类,运行环境:运行机制和内核,用户态非特权,核心态特权,中断技术,访管指令 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得 ...

  8. 【操作系统基础知识 一】操作系统基本原理

    学生时代没有好好学习操作系统,悔不当初,现在重新捡起来看看,才发现日常有很多事情都可以解释了,例如为什么Linux快!并发是什么?操作系统到底干啥活,这篇blog是王道的学习笔记: 操作系统基本概念, ...

  9. 操作系统概念 ppt_智能家居操作系统三国拉锯,要出结果了吗?

    海尔.百度.华为盘踞的智能家居操作系统,谁拿下传统家电企业了? 文/郭锴 来源/智能相对论(aixdlun) 福特曾说,如果你问消费者他们想要什么,得到的答案只会是一匹更快的马.汽车大王福特给消费者了 ...

最新文章

  1. 全球大半网络瘫痪,背后原因竟来自这家无名小公司
  2. 【LeetCode从零单排】No38.CountAndSay
  3. 优化UGC流程,获得图文并茂游记so easy
  4. oracle改成归档模式_oracle 11g开启归档模式及修改归档目录
  5. 什么是覆盖索引?如何利用覆盖索引进行SQL语句优化?
  6. 第 6-3 课:SpringBoot 核心 + 面试题
  7. 看看我写的文章,牛逼不。哈哈。
  8. Python调用(运行)外部程序参数问题
  9. 信息服务器恢复需要多少时间,云服务器灾难恢复的4个计划
  10. python求曲线拐点_如何发现拐点?
  11. Java学习-Overload和Override的区别
  12. TCP/IP协议简介
  13. Maven 梳理 - Maven中的dependencyManagement 意义
  14. [UE4]Uniform Grid Panel
  15. 【读书笔记《Android游戏编程之从零开始》】6.Android 游戏开发常用的系统控件(TabHost、ListView)
  16. ROS系统学习8---节点间的内存共享(初级篇)
  17. 使用宏破解EXCEL工作表保护密码的方法
  18. python上传文件到云服务器,python基于paramiko将文件上传到服务器代码实现
  19. iPhone/iPad/Android UI尺寸规范 手机尺寸
  20. 完美世界前三季营收57亿同比降15% 净利14.4亿同比增80%

热门文章

  1. pom.xml中的dependency标签的classifier
  2. FlinkCdc从Mysql指定的binlog日志offsetPos位置开始读取数据
  3. html toast屏幕中间,Toast.html
  4. rds mysql 表被删了_MySQL · 捉虫动态 · 删除索引导致表无法打开
  5. Java多线程共享变量控制
  6. Spring Boot 之异步执行方法
  7. android window设置动画,android - 具有动画的Windowmanager
  8. linux思科认证,思科CCIE认证知识点之IPv6地址
  9. Go36-13-结构体及其方法
  10. 深入理解Auto Layout 第一弹