实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

王康 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

系统调用:操作系统中,程序员通过封装好的库函数来实现系统调用

前提

1,用户态内核态中断:

1,用户态内核态区分:(低级别即用户态)

为什么有权限级别划分?让系统本身更稳定的机制

wpsEE40.tmp

如何区分?内核态是任意地址x86有4G内存地址空间;用户只能访问到0xbfffffff,c以上只能内核态

逻辑地址经过MMU转化为物理地址。

wpsEE41.tmp

2,中断处理是从用户态进入内核态的主要方式

硬中断,或者系统调用陷入trap。

系统调用是一种特殊的中断。

同时也保存内核态esp,状态字,内核态当前中断处理程序入口指向system.call函数

wpsEE42.tmp

wpsEE43.tmp

iret对应中断信号或者int指令,那边是保存,iret就是恢复

wpsEE44.tmp

3,中断完整过程

int 0x80是系统调用:1,保存了eip,当前ss堆栈段寄存器esp;eflags标志寄存器保存至内核堆栈

2,同时加载了ISR中断服务程序入口至cseip,然后当前esp指向内核堆栈段信息

wpsEE54.tmp

3,SAVE_ALL完成后开始中断服务,可能会发生进程调度;

如果发生了进程调度,当前的SAVE_ALL都会暂时保存在系统里边,再切换回来时恢复

4,RESTORE_ALL,iret

2,系统调用概述

wpsEE55.tmp

也防止了用户直接与操作系统打交道,提高安全性与可移植性(用户程序与具体硬件已经解耦和,被抽象接口替代了)

wpsEE56.tmp

系统调用封装成了一个函数API,区分是:API只是为了便于系统调用而产生的,通过汇编也可以完成系统调用功能

软中断是通过trap方式有int请求的

wpsEE57.tmp

wpsEE58.tmp

xyz()是个API,内部封装了系统调用触发了int 0x80,这个中断向量对应着system_call内核代码入口起点。

服务程序sys_xyz执行完后ret_from_sys_call,这个过程中返回后则是进程调度的实际。

三层皮:

wpsEE59.tmp

wpsEE5A.tmp

wpsEE5B.tmp

wpsEE5C.tmp

系统调用参数传递:

wpsEE5D.tmp

超过6个就把某一个寄存器做指针指向内存,通过那一块内存来传递(NR应该是NUMBER缩写,即)

eax传递的系统调用号即int 0xxx的这个号至少为一个参数

(eax传入的0Xd即为系统调用号13,int0x80调用system_call)

2,使用库函数API和C代码中嵌入汇编代码触发同一个系统调用

wpsEE5E.tmp

tt是int型数值,需要变为年月日

tm是年月日格式struct

time是系统调用

之后变为tm格式

1,c代码中嵌入汇编代码写法

输出输入部分是参数,return也是一个参数部分

wpsEE5F.tmp

实例:

wpsEE60.tmp

%%转义 ; 编译器自动帮你把val1的值放入ecx edx寄存器

=m 即写入内存变量

wpsEE61.tmp

= 意思是操作数在指令中是只写的 ;  + 是操作数为读写类型

r是通用寄存器

最后eax是破坏描述部分

3,用汇编方式触发系统调用获取系统当前时间

wpsEE62.tmp

把ebx请0;eax传入的0Xd即为系统调用号13,int0x80调用system_call

wpsEE63.tmp

如同之前c语言的time(null)

wpsEE74.tmp

4,实验部分

方法一:使用API在屏幕上显示“hello world”

这个其实也是C语言经典的入门程序,源代码如下

1. #include "stdio.h"  

2. #include "string.h"  

3.

4. int main()  

5. {  

6.     char* msg = "Hello World";  

7.     printf("%s", msg);  

8.     return 0;  

9. }  

gedit helloworld.c,新建并打开helloworld.c文件,在其中输入上面的代码,保存退出;

然后使用下面的指令编译链接程序:

1. gcc -o helloworld helloworld.c -m32   

接着,运行编译好的程序,

./helloworld

效果如下:

wpsEE75.tmp

方法二:使用C内嵌汇编代码在屏幕上输出helloworld

Linux中内嵌汇编代码:

1. int main()  

2. {  

3.     char* msg = "Hello World";  

4.     int len = 11;  

5.     int result = 0;  

6.

7.     __asm__ __volatile__("movl %2, %%edx;\n\r" /*传入参数:要显示的字符串长度*/  

8. "movl %1, %%ecx;\n\r" /*传入参赛:文件描述符(stdout)*/  

9.  "movl $1, %%ebx;\n\r" /*传入参数:要显示的字符串*/  

10.              "movl $4, %%eax;\n\r" /*系统调用号:4 sys_write*/  

11.              "int  $0x80" /*触发系统调用中断*/  

12.              :"=m"(result) /*输出部分:本例并未使用*/  

13.  :"m"(msg),"r"(len)  /*输入部分:绑定字符串和字符串长度变量*/  

14.              :"%eax");   

15.

16.     return 0;  

17. }  

使用gedit helloworld_asm.c新建文件,并输入上面的代码,使用下面的命令编译

gcc -o helloworld_asm helloworld_asm.c -m32

使用下面的命令运行

./helloworld_asm

运行效果如下

wpsEE76.tmp

5,总结

即便是最简单的程序,也难免要用到诸如输入、输出以及退出等操作,而要进行这些操作则需要调用操作系统所提供的服务,也就是系统调用。除非你的程序只完成加减乘除等数学运算,否则将很难避免使用系统调用。在 Linux 平台下有两种方式来使用系统调用:利用封装后的 C 库(libc)或者通过汇编直接调用。
Linux 下的系统调用是通过中断(int 0x80)来实现的。在执行 int 80 指令时,寄存器 eax 中存放的是系统调用的功能号,而传给系统调用的参数则必须按顺序放到寄存器 ebx,ecx,edx,esi,edi 中,当系统调用完成之后,返回值可以在寄存器 eax 中获得。
所有的系统调用功能号都可以在文件 /usr/include/bits/syscall.h 中找到,为了便于使用,它们是用 SYS_<name> 这样的宏来定义的,如 SYS_write、SYS_exit 等。例如,经常用到的 write 函数是如下定义的:
ssize_t write(int fd, const void *buf, size_t count);
该函数的功能最终是通过 SYS_write 这一系统调用来实现的。根据上面的约定,参数 fb、buf 和 count 分别存在寄存器 ebx、ecx 和 edx 中,而系统调用号 SYS_write 则放在寄存器 eax 中,当 int 0x80 指令执行完毕后,返回值可以从寄存器 eax 中获得。
或许你已经发现,在进行系统调用时至多只有 5 个寄存器能够用来保存参数,难道所有系统调用的参数个数都不超过 5 吗?当然不是,例如 mmap 函数就有 6 个参数,这些参数最后都需要传递给系统调用 SYS_mmap:
void  *  mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
当一个系统调用所需的参数个数大于 5 时,执行int 0x80 指令时仍需将系统调用功能号保存在寄存器 eax 中,所不同的只是全部参数应该依次放在一块连续的内存区域里,同时在寄存器 ebx 中保存指向该内存区域的指针。系统调用完成之后,返回值仍将保存在寄存器 eax 中。
由于只是需要一块连续的内存区域来保存系统调用的参数,因此完全可以像普通的函数调用一样使用栈(stack)来传递系统调用所需的参数。但要注意一点,Linux 采用的是 C 语言的调用模式,这就意味着所有参数必须以相反的顺序进栈,即最后一个参数先入栈,而第一个参数则最后入栈。如果采用栈来传递系统调用所需的参数,在执行int 0x80 指令时还应该将栈指针的当前值复制到寄存器 ebx中。

转载于:https://www.cnblogs.com/wk2016just/p/6536831.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络理论篇】 37 常用文本处理工具:spaCy库+torchtext库

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

海龟画图 python太阳花_python 简单的绘图工具turtle使用详解

目录 1. 画布(canvas) 1.1 设置画布大小 2. 画笔 2.1 画笔的状态 2.2 画笔的属性 2.3 绘图命令 3. 命令详解 4. 绘图举例 4.1 太阳花 4.2 绘制小蟒蛇 4.3 绘制五角星 python2.6版本中后引入的一个简单的绘图工具&#xff0c;叫做海龟绘图(Turtle Graphics),turtle库是python的内…

【Pytorch神经网络实战案例】31 TextCNN模型分析IMDB数据集评论的积极与消极

卷积神经网络不仅在图像视觉领域有很好的效果&#xff0c;而且在基于文本的NLP领域也有很好的效果。TextCN如模型是卷积神经网络用于文本处理方面的一个模型。 在TextCNN模型中&#xff0c;通过多分支卷积技术实现对文本的分类功能。 1 TextCNN 1.1 TextCNN模型结构 TexCNN…

python怎么画出好看的统计图_用最简单的 Python ,画最好看的图 [简单数据可视化]...

可以直接修改参数使用&#xff0c;非常的方便。import numpy as np import pandas as pd import holoviews as hv hv.extension(bokeh) macro_df pd.read_csv(http://assets.holoviews.org/macro.csv, \t) key_dimensions [(year, Year), (country, Country)] value_dimensio…

combobox之下拉宽度自适应

效果对比 先看下优化前后的效果&#xff0c;再看实现过程. 优化前 优化后 从上图中可看到&#xff0c;combobox优化后可以自适应不同长度的字符串&#xff0c;保证每个字符串都能够显示完整。 实现过程 当我们触发CBN_DROPDOWN事件时&#xff0c;不再使用默认的实现&#xff0c…

Python工具:将文件夹下的视频按照帧数输出图片文件(含代码)

1、描述 将一个视频流按帧数截取大量的图片 2、用途 AI的数据集制作&#xff0c;得到大量的图片&#xff0c;之后将其打标签 3、案例文件截图 4、代码实现&#xff1a; import cv2 import argparse import os# 边里该文件夹下的文件名称 def read_directory(directory_nam…

用Python语言对任意图像进行m*n的均匀分块(思路非常清晰,步骤简单)

主要用途&#xff1a;处理图片数据集 1 对单个图片进行分块 import numpy as np import matplotlib.pyplot as plt import cv2def divide_method1(img,m,n):#分割成m行n列print(img.shape)h, w img.shape[0],img.shape[1]gx np.round(h).astype(np.int)gy np.round(w).asty…

python爬虫用什么软件写_python爬虫怎么写

如今很多有编程能力的小伙伴已经不满足手动搜索内容了&#xff0c;都希望通过编写爬虫软件来快速获取需要的内容&#xff0c;那么如何使用python制作爬虫呢&#xff1f;下面小编给大家讲解一下思路 工具/原料 python 方法/步骤 1 首先我们需要确定要爬取的目标页面内容&#xf…

花书《深度学习》代码实现:01 线性代数:基本概念+代码实现基本运算

1 标量、向量、矩阵和张量 2 矩阵和向量相乘 3 单位矩阵和逆矩阵 3.0 单位矩阵 a np.identity(3) # 三行三列单位矩阵 3.1 矩阵的逆 A [[1.0,2.0],[3.0,4.0]] A_inv np.linalg.inv(A) print("A 的逆矩阵", A_inv) 3.1 转置 A np.array([[1.0,2.0],[1.0,0…

【Pytorch神经网络理论篇】 38 Transformers:安装说明+应用结构+AutoModel类

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

clone是深拷贝还是浅拷贝_Python中的浅拷贝和深拷贝

本文翻译自copy in Python (Deep Copy and Shallow Copy)&#xff0c;讲述了在Python语言中浅拷贝与深拷贝的不同用法。全文系作者原创&#xff0c;仅供学习参考使用&#xff0c;转载授权请私信联系&#xff0c;否则将视为侵权行为。码字不易&#xff0c;感谢支持。以下为全文内…

【Pytorch神经网络实战案例】32 使用Transformers库的管道方式实现:加载指定模型+文本分类+掩码语言建模+摘要生成+特征提取+阅读理解+实体词识别

管道方式是Transformers库中高度集成的极简使用方式。使用这种方式来处理NLP任务&#xff0c;只需要编写几行代码就能实现。通过本例的练习可以使读者对Transformers库的使用快速上手。 1 在管道方式中指定NLP任务 Transfomers库的管道方式使用起来非常简单&#xff0c;核心步…

jqprint获取打印页数_如何将每张打印多页PPT的PDF变成常规课件

在工作和学习中&#xff0c;经常会收到各种 PDF 文件&#xff0c;尤其是老师的课件。为了防止学生大量上传到各种文库网站赚积分&#xff0c;或者为了方便学生打印出来预习复习。通常&#xff0c;会在每页 PDF 里面&#xff0c;打印多张 PPT 内容。一般是 6 张或 9 张&#xff…

vba 判断文本框内容是否为空_【VBA】 数据输入 Inputbox 基本语法

在使用Excel 的过程中&#xff0c;如果需要用户输入简单的数据&#xff0c;作为“已知数”&#xff0c;那么可以使用inputbox 函数显示一个对话框&#xff0c;供用户在对话框中输入数据。 Inputbox 函数语法在一对话框来中显示提示&#xff0c;等待用户输入正文或按下按钮&…

无向图的深度优先遍历非递归_LeetCode0429: N叉树的层序遍历

题目介绍描述&#xff1a;给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。 (即从左到右&#xff0c;逐层遍历)。例如&#xff0c;给定一个 3叉树 :返回其层序遍历:[[1],[3,2,4],[5,6] ]说明:树的深度不会超过 1000。 树的节点总数不会超过 5000。解题思路&#xff1a;★ …

一条龙操作有效解决PermissionError: [WinError 5] 拒绝访问的问题

1 问题描述 当在使用pip install 安装包时&#xff0c;如&#xff1a;pip install scrapy scrapyd scrapyd-client spiderkeeper出现报错&#xff1a;PermissionError: [WinError 5] 拒绝访问。: ‘c:\programdata\anaconda3\lib\site-packages\dateutil\easter.py’ 2 解决办…

预订态势图

//预订态势图JS//根据日期得到对应星期几 function getWeekByDay(riqi){//2017-01-23;var getWeek "";var arys1 new Array(); arys1riqi.split(-); //日期为输入日期&#xff0c;格式为 2013-3-10var ssdatenew Date(arys1[0],parseInt(arys1[1]-1),arys1…

altera fpga sdi输出方案_FPGA在电力电子中的应用有哪些?

大家好&#xff0c;很抱歉上周末没有及时更新公众号&#xff0c;本来这期想聊聊IGBT的拖尾电流&#xff0c;但是由于周末去深圳高交会(高新技术成果交易会)逛了一天&#xff0c;时间给耽搁了&#xff0c;感觉要想把拖尾电流讲清楚也不太容易&#xff0c;还得需要点时间&#xf…

【Pytorch神经网络理论篇】 39 Transformers库中的BERTology系列模型

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

Unity之CharacterController2D学习笔记(1)——基础使用

在很多游戏类型中&#xff0c;玩家角色对物理行为的处理往往和场景中其它物体的行为有比较大的区别。比如角色可能会以90多公里的时速狂奔&#xff0c;同时一次跳跃能跳10多米高&#xff0c;与此同时却几乎不会有任何惯性。同时角色在正常情况下当头部碰到障碍物的时候&#xf…