Linux系统64位ATT系统调用汇编指令syscall

news2024/9/27 19:26:14

相关概念

在Linux中syscall系统调用(英文:system call)的指令。
想要深入了解syscall的作用,就需要了解特权级别。
现代计算机通常采用名为保护环(Protection Rings)的机制来保护整个系统的数据和功能,使其免受故障和外部恶意行为的伤害。这种方式通过提供多种不同层次的资源访问级别,即特权级别,来限制不同代码的执行能力。
Intel x86 架构中,特权级别被分为 4 个层次,即Ring0~Ring3。其中,Ring0层拥有最高特权,它具有对整个系统的最大控制能力,内核代码通常运行于此。相对地,Ring3层只有最低特权,这里是应用程序代码所处的位置。而位于两者之间的 Ring1Ring2层,则通常被操作系统选择性地作为设备驱动程序的“运行等级”。
在这里插入图片描述

根据特权级别的不同,CPU 能够被允许执行的机器指令、可使用的寄存器和可用的硬件资源也随之不同。比如位于Ring3层的应用程序,可以使用最常见的通用目的寄存器,并通过mov指令操作其中存放的数据。而位于 Ring0 层的内核代码则可以使用除此之外的cr0cr1等控制寄存器,甚至通过inout等机器指令,直接与特定端口进行 IO 操作。但如果应用程序尝试跨级别非法访问这些被限制的资源,CPU 将抛出相应异常,阻止相关代码的执行。
系统调用是操作系统提供的接口,逻辑上跟用户函数相似,能够帮助程序切换到进程的内核空间执行功能。也就是说,应用程序可以通过系统调用进入到操作系统内核空间完成某项功能。系统调用过程通常称为特权模式切换
《Unix环境高级编程》里边系统调用的图

系统调用一般函数(或者说用户函数)的最大区别在于,系统调用执行的代码位于操作系统底层的内核环境(内核环境也称作内核空间或应用程序的内核态,处于CPU特权等级Ring0)中,而用户函数代码则位于内核之上的应用环境(应用环境也称作用户空间或者应用程序的用户态,处于Ring3)中。
在使用系统调用时,rax寄存器里边需要放入系统调用号,表明需要执行的系统调用,/usr/include/asm/unistd_64.h可以看64位Linux系统调用和系统调用号的对应关系,可以使用man 2 系统调用查询如何使用系统调用,而系统调用就是在/usr/include/asm/unistd_64.h__NR_后边的字符串,比如readselectsocket等。
cat /usr/include/asm/unistd_64.h可以看64位Linux系统调用和系统调用号的对应关系。
在这里插入图片描述

man 2 exit可以看一下系统调用exit的相关信息,按q可以退出man界面。
在这里插入图片描述

系统调用使用到的寄存器:

寄存器作用
rax放入系统调用号
rdi第1个参数
rsi第2个参数
rdx第3个参数
r10第4个参数
r9第5个参数
r8第6个参数

除了系统调用号,内核还需要知道需要处理的参数,这就需要使用rdirsirdxr10r9r8等六个寄存器传递参数,系统调用最多只能传递6个参数。

返回值会放到rax寄存器里边,rcx在系统调用时会保存下一条指令位置,r11会保存eflags的数值。

示例

在C语言中使用系统调用,可以参考博客。

输出字符串

输出字符串使用到的寄存器和应该赋予的值:

寄存器
rax1
rdi文件描述符,要是想要输出到屏幕上,那么就需要把rdi赋值为1
rsi输出字符串的地址
rdx输出的字符个数

上边的表是系统调用之前进行放置的。
在系统调用完成之后rax会被放入返回值。
AT&T汇编代码displayStringATT64.s里边的代码如下:

.global main
.section .data
# 需要输出的字符串
stringToShow:
        .ascii "hello world\n\0"
.section .text
main:
        # 系统调用号,可以看一下/usr/include/asm/unistd_64.h里边功能和调用号对应关系
        movq $1,%rax
        # %rdi里边放的是系统调用write函数第一个参数,表示输出的位置,当rdi里边的数值是1,表明需要输出到标准输出
        movq $1,%rdi
        # %rsi里边放入的是系统调用write函数第二个参数,表示输出的内容
        movq $stringToShow,%rsi
        # %rsi里边放入的是系统调用write函数第三个参数,表示输出的内容长度,这里字符串的长度,包括“\n”,而不包括“\0”
        movq $12,%rdx
        syscall

       # 相当于C语言中的return 0
        movq $60,%rax
        movq $0,%rdi
        syscall

gcc displayStringATT64.s -o displayStringATT64把汇编代码进行编译,编译完成之后./displayStringATT64执行就会输出hello world
在这里插入图片描述
上边的汇编代码相当于下边的C语言stdoutputSimple.c代码:

#include <unistd.h>

int main()
{
    write(1,"hello world\n",12);
    return 0;
}

使用gcc stdoutputSimple.c -o stdoutputSimple进行编译,然后使用./stdoutputSimple执行输出hello world
在这里插入图片描述

输入字符串

输入字符串需要使用的寄存器及相应的赋值:

寄存器
rax0
rdi输入的位置,使用文件描述符进行表示,要是从标准输入读取的话,赋值为0
rsi读取字符串的位置
rdx读取的字符个数

从键盘上输入字符串到屏幕的AT&T汇编代码consoleInputATT.s里边的内容如下:

.section .data
        stringLength: .quad 5
        prompt:
            .ascii "Please input:"

.section .bss
        stringToFile: .skip 7
        oneChar: .skip 1

.section .text
.global main
    main:
        # rax = 1,输出的系统调用号
        movq $1,%rax
        movq $1,%rdi
        movq $prompt,%rsi
        movq $13,%rdx
        syscall

        # 此处取地址
        leaq oneChar,%rbx
        leaq stringToFile,%r10
        movq $0,%r12


    readCharacters:
        movq $0,%rax
        movq $0,%rdi
        movq %rbx,%rsi
        movq $1,%rdx
        syscall


        # 取值
        movq (%rbx),%rax
        cmpb $10,%al
        je printString

        incq %r12
        cmpq %r12,stringLength
        jb readCharacters

        movb %al,(%r10)
        incq %r10
        

        jmp readCharacters

    printString:
        incq %r10
        movb $10,(%r10)
        incq %r10
        movb $0,(%r10)
        movq $1,%rax
        movq $1,%rdi
        movq $stringToFile,%rsi
        movq %r12,%rdx
        syscall

        movq $60,%rax
        movq $0,%rdi
        syscall

gcc -g consoleInputATT.s -o consoleInputATT进行编译,./consoleInputATT执行,然后输入1234567,发现最后输出的是12345,符合预期,最多只能输入5个字符。
在这里插入图片描述

创建文件

在系统调用之前,需要放入值的寄存器和对应的值:

寄存器
rax85
rdi文件名称,需要以ASCII中的0(NULL)结束
rsi文件访问权限

fileCreateATT.s里边的代码如下:

.global main
.section .data
    # 文件名称,”\0“是NULL的含义
    fileName:
        .ascii "fileText.txt\0"
.section .text
    # main函数
    main:
        # rax = 85,告诉内核需要创建文件
        movq $85,%rax
        # rdi = 文件名称,告诉内核创建文件的名称
        movq $fileName,%rdi
        # rsi = 文件访问权限,告诉内核文件是否有读、写、执行等权限
        movq $0600,%rsi
        syscall
        
	   # rax = 60,这是退出程序的系统调用号
        movq $60,%rax
        movq $0,%rdi
        syscall

gcc fileCreateATT.s -o fileCreateATT进行编译,ls -l fileText.txt若是显示ls: cannot access fileText.txt: No such file or directory,那么说明没有fileText.txt这个文件,./fileCreateATT进行执行,ls -l fileText.txt就可以显示文件的信息了,这说明创建成功了fileText.txt文件。
在这里插入图片描述

可以使用rm -rf fileText.txt删除已经创建的文件
在这里插入图片描述

创建文件并写入字符串

fileWriteATT.s里边的代码如下:

.global main
.section .data
    fileName:
        .ascii "writeToFile.txt\0"
    fileContextString:
        .ascii "good learn!\n\0"

.section .text
    main:
        movq $85,%rax
        movq $fileName,%rdi
        movq $0600,%rsi
        syscall

        # rax在系统调用之后就保存文件描述符,这里把文件描述符从rax中保存到rdi中
        movq %rax,%rdi
        movq $1,%rax
        movq $fileContextString,%rsi
        movq $12,%rdx
        syscall

        movq $60,%rax
        movq $0,%rdi
        syscall

gcc fileWriteATT.s -o fileWriteATT进行编译,./fileWriteATT进行执行,cat writeToFile.txt查看写入writeToFile.txt文件里边的内容。
在这里插入图片描述

关闭文件

关闭一个文件需要使用到的寄存器及相应的赋值:

寄存器
rax3
rdi文件描述符

此处的例子跟底下的打开文件读取文件里边内容例子写在一起。

打开文件读取文件里边内容

打开一个文件需要使用到的寄存器及相应的赋值:

寄存器
rax2
rdi文件名称
rsi文件访问权限

需要注意的是,在系统调用之后,rax里边就会放入文件描述符返回,之后可以通过这个文件描述符才可以对这个文件进行操作,比如读写。

fileReadATT.s里边的内容如下:

.section .data
        fileName:
            .ascii "writeToFile.txt\0"
        fileDescriptor: .quad 0
.section .bss
        stringFromFile: .skip 14
.global main
.section .text
    main:
        movq $2,%rax
        movq $fileName,%rdi
        movq $00,%rsi
        movq $0444, %rdx
        syscall

        cmpq $0,%rax
        jbe done
        movq %rax,fileDescriptor


        movq $0,%rax
        movq fileDescriptor,%rdi
        movq $stringFromFile,%rsi
        movq $11,%rdx
        syscall

        movq $stringFromFile,%rdi
        movb $'\n',12(%rdi)
        # movb $'\0',13(%rdi)
        


        movq $1,%rax
        movq $1,%rdi
        movq $stringFromFile,%rsi
        movq $13,%rdx
        syscall
        
        movq $3,%rax
        movq fileDescriptor,%rdi
        syscall
	done:
        movq $60,%rax
        movq $0,%rdi
        syscall

gcc -g fileReadATT.s -o fileReadATT进行编译,上边产生可执行文件./fileWriteATT先执行产生一个writeToFile.txt文件,cat writeToFile.txt可以看一下writeToFile.txt文件里边的内容,确保上边程序执行正确,./fileReadATT执行读取文件内容。
在这里插入图片描述

讲到系统调用的汇编语言书籍:

书籍作者章节章节名语言汇编语言风格汇编器
x64汇编语言:从新手到AVX专家Jo Van Hoey第20章文件I/O汉语Intelnasm
Low-Level Programming: C, Assembly, and Program Execution on Intel 64 ArchitectureIgor Zhirkov第6章Interrupts and System Calls英语Intelnasm
Introduction to 64 Bit Intel Assembly Language Programming for LinuxRay Seyfarth第12章System calls英语Intelyasm
x86-64 Assembly Language Programming with UbuntuEd Jorgensen第13章System Services英语Intelyasm
Introduction to Computer Organization: An Under-the-Hood Look at Hardware and x86-64 AssemblyRobert G. Plantz第21章Interrupts and Exceptions英语Intelgas
Learn to Program with Assembly: Foundational Learning for New ProgrammersJonathan Bartlett第10章Making a System Calls英语AT&Tgas

此文章为10月Day 24学习笔记,内容来源于极客时间《深入 C 语言和程序运行原理》。

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

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

相关文章

出海 SaaS 企业增长修炼手册2:Kyligence 落地 PLG 是如何避坑的?

在第一篇文章&#xff08;点击阅读 &#x1f449; 出海 SaaS 企业增长修炼手册&#xff1a;聊聊 PLG 的关键指标、技术栈和挑战&#xff09;中&#xff0c;我们分享了 SaaS 企业在落地 PLG 战略中可能遇到的挑战以及相应的解决方案&#xff0c;今天我们将从 Kyligence 亲身实践…

【数据结构】数组和字符串(二):特殊矩阵的压缩存储:对角矩阵——一维数组

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储结构体初始化元素设置元素获取打印矩阵主函数输出结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串&#xff08;一&#xff09;&#xff1a;矩阵的数组表示 4.2.2 特殊矩阵的压缩存储…

Qt之普通项目如何生成DLL(含源码+注释)

文章目录 一、示例图二、普通项目需要改造的内容三、源码&#xff08;创建了一个TestDLL的项目&#xff0c;更改内容主要在pro文件和maindow.h文件&#xff09;TestDLL.promainwindow.hmainwindow.cppmainwindow.ui 总结 一、示例图 使用不同的编译模式编译&#xff0c;会在对…

卷积神经网络的感受野

经典目标检测和最新目标跟踪都用到了RPN(region proposal network)&#xff0c;锚框(anchor)是RPN的基础&#xff0c;感受野(receptive field, RF)是anchor的基础。本文介绍感受野及其计算方法&#xff0c;和有效感受野概念。 1.感受野概念 在典型CNN结构中&#xff0c;FC层(…

一款集成了主流大语言模型以及绘图模型的 APP, 采用 Flutter 开发,代码完全开源!!

一款集成了主流大语言模型以及绘图模型的 APP&#xff0c; 采用 Flutter 开发&#xff0c;代码完全开源&#xff0c;支持以下功能&#xff1a; 支持 OpenAI 的 GPT-3.5&#xff0c;GPT-4 大语言模型支持 Anthropic 的 Claude instant&#xff0c;Claude 2.0 大语言模型支持国产…

Python 框架学习 Django篇 (六) 数据表关联、ORM关联

在后端服务器开发中&#xff0c;特别是前后端分离的架构中数据库是非常重要的&#xff0c;后端主要就是负责管理数据&#xff0c;而我们经常使用的mysql、oracle 都是关系型数据库&#xff0c;什么是关系型数据库&#xff1f;就是建立在关系模型基础上的数据库&#xff0c;而最…

竞赛 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

flutter 使用FlutterJsonBeanFactory工具遇到的问题

如下图&#xff0c;使用FlutterJsonBeanFactory工具生成的数据类 但是其中 生成的 import package:null/&#xff0c;导致的错误&#xff1a;Target of URI doesn’t exist: ‘package:null/generated/json/asd.g.dart’ 尝试过的方法&#xff1a; 手动添加包名&#xff0c;…

面试算法39:直方图最大矩形面积

题目 直方图是由排列在同一基线上的相邻柱子组成的图形。输入一个由非负数组成的数组&#xff0c;数组中的数字是直方图中柱子的高。求直方图中最大矩形面积。假设直方图中柱子的宽都为1。例如&#xff0c;输入数组[3&#xff0c;2&#xff0c;5&#xff0c;4&#xff0c;6&am…

前后端交互系统:在Node.js中运行JavaScript

在Node.js中运行JavaScript&#xff0c;您需要编写适用于服务器端的代码&#xff0c;而不是浏览器端的代码。以下是一些示例代码&#xff0c;用于在Node.js中创建一个简单的HTTP服务器并在浏览器中访问它&#xff1a; // 引入Node.js内置的http模块 const http require(http);…

华为ERP,包含哪些内容?技术的先进性体现在哪里?

华为作为全球领先的信息和通信技术&#xff08;ICT&#xff09;解决方案提供商&#xff0c;其企业资源规划&#xff08;ERP&#xff09;系统是一个高度复杂且集成的管理软件平台&#xff0c;用于优化公司内部的业务流程和资源分配。华为ERP系统包括一系列模块和功能&#xff0c…

pytest-yaml 测试平台-2.支持上传YAML格式用例

前言 pytest-yaml 测试平台用例结构是遵循pytest-yaml-yoyo 框架用例规则。 如果你之前已经有用 pytest-yaml-yoyo 框架完成了yaml 用例的编写&#xff0c;可以直接在平台上导入yaml 用例。 yaml 用例 test_用例文件a.yml config:name: 单个用例文件test_a:name: extract提…

Linux多线程服务端编程:使用muduo C++网络库 学习笔记 第三章 多线程服务器的适用场合与常用编程模型

本文中的多线程服务器指运行在Linux上的独占式网络应用程序。硬件平台为Intel x86-64系列的多核CPU&#xff0c;单路或双路SMP&#xff08;Symmetric Multi-Processing&#xff0c;对称多处理&#xff0c;它是一种多核处理器架构&#xff0c;其中多个CPU核心共享系统的内存和其…

(三)行为模式:10、策略模式(Strategy Pattern)(C++示例)

目录 1、策略模式&#xff08;Strategy Pattern&#xff09;含义 2、策略模式的UML图学习 3、策略模式的应用场景 4、策略模式的优缺点 &#xff08;1&#xff09;优点&#xff1a; &#xff08;2&#xff09;缺点 5、C实现策略模式的实例 6、策略模式解析 1、策略模式…

解决报错:gnutls_handshake() failed: The TLS connection was non-properly terminated.

执行git clone的时候&#xff0c;出现错误&#xff1a;gnutls_handshake() failed: The TLS connection was non-properly terminated. 如图&#xff1a; 解决方式&#xff1a; 两次重置代理&#xff1a;完美解决 git config --global --unset https.https://github.com.pro…

批量编辑 Outlook 联系人

现状 Outlook 自带的联系人编辑功能无法快速、批量编辑联系人字段使用 Excel 等外部编辑器&#xff0c;可批量编辑联系人 导出联系人到文件 在【联系人】界面&#xff0c;点击【文件】在【文件】界面&#xff0c;点击【打开和导出】–>【导入/导出】在弹出的向导窗口中点…

[C国演义] 第十七章

第十七章 摆动序列最长递增子序列的个数 摆动序列 力扣链接 子序列 ⇒ dp[i]的含义: 以nums[i] 为结尾的所有子序列中的 摆动序列中的最长长度子序列 ⇒ 状态转移方程: 最后一个元素的构成 初始化: 都初始化为 1 遍历方向: 从前往后返回结果: f表 和 g表中的最大值 class …

解决Typora闪退、文件打不开等问题——Typora免费使用教程(也有免费版的)

问题描述&#xff1a; 下好Typora之后打开会闪退&#xff0c;程序运行一会之后就自己关闭了&#xff0c;显示出一片空白&#xff0c;以前写的文件也打不开。 经过一番搜索&#xff0c;发现大佬的文章&#xff0c;给出了很详细的原因分析、解决过程&#xff1b; 具体参考如下&…

【1.2】神经网络:神经元与激活函数

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 神经网络&#xff08;随缘更新&#xff09; ✨特色…

[数据结构]-二叉搜索树

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、二叉搜…