草庐IT

linux - 系统调用的良好引用

coder 2023-06-19 原文

我需要一些引用,但需要一个好的引用,可能还带有一些不错的示例。我需要它,因为我开始使用NASM汇编器在汇编中编写代码。我有这个引用:

http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html

这是非常好的和有用的,但是它有很多限制,因为它没有解释其他寄存器中的字段。例如,如果我使用write syscall,我知道我应该在EAX寄存器中放入1,而ECX可能是指向该字符串的指针,但是EBX和EDX呢?我也想解释一下,EBX确定输入(stdin为0,其他为1等),EDX为要输入的字符串的长度,以此类推。等等。我希望您理解我想要的内容,我找不到任何此类 Material ,所以这就是我在这里写的原因。
提前致谢。

最佳答案

Linux中的标准编程语言是C。因此,对系统调用的最佳描述将其显示为要调用的C函数。给定它们作为C函数的描述,以及如何将它们映射到汇编中的实际系统调用的知识,您将能够轻松使用所需的任何系统调用。

首先,您需要一个对所有系统调用都像C程序员一样的引用。我所知道的最好的是Linux man-pages project,尤其是system calls部分。

让我们以 write 系统调用为例,因为它是您所提出的问题。如您所见,第一个参数是一个有符号整数,通常是open syscall返回的文件描述符。这些文件描述符也可能已经从您的父进程继承,就像通常发生在前三个文件描述符(0 = stdin,1 = stdout,2 = stderr)一样。第二个参数是指向缓冲区的指针,第三个参数是缓冲区的大小(无符号整数)。最后,该函数返回一个有符号整数,即已写入的字节数,或者为错误的负数。

现在,如何将其映射到实际的系统调用?在32位x86上进行系统调用的方法有很多(根据您的寄存器名称,这可能是您正在使用的方法)。请注意,它在64位x86上是完全不同的(请确保在32位模式下进行汇编并链接32位可执行文件;有关其他如何出错的示例,请参见this question)。在32位x86中,最古老,最简单和最慢的是int $0x80方法。

对于int $0x80方法,将系统调用号依次放在%eax中,并将参数依次放在%ebx%ecx%edx%esi%edi%ebp中。然后调用int $0x80,系统调用的返回值在%eax上。请注意,该返回值与引用文献所说的不同。引用资料显示了C库将如何返回它,但是系统调用会在出错时返回-errno(例如-EINVAL)。在这种情况下,C库会将其移至errno并返回-1。有关更多详细信息,请参见syscalls(2)intro(2)

因此,在write示例中,您可以将write系统调用号放入%eax中,将第一个参数(文件描述符号)放入%ebx中,将第二个参数(指向字符串的指针)放入%ecx中,并将第三个参数(字符串的长度) )在%edx中。系统调用将以%eax返回写入的字节数或错误号被取反(如果返回值在-1到-4095之间,则它是取反的错误号)。

最后,您如何找到系统电话号码?可以在/usr/include/linux/unistd.h上找到它们。在我的系统上,它只包含/usr/include/asm/unistd.h,最后包含/usr/include/asm/unistd_32.h,所以数字在那里(对于write,您可以看到__NR_write4)。错误编号也是如此,它们来自/usr/include/linux/errno.h(在我的系统上,在追踪包含链之后,我发现第一个错误代码在/usr/include/asm-generic/errno-base.h上,其余的错误代码在/usr/include/asm-generic/errno.h上)。对于使用其他常量或结构的系统调用,其文档说明了应查看哪些 header 才能找到相应的定义。

现在,正如我所说的,int $0x80是最古老,最慢的方法。较新的处理器具有更快的特殊系统调用指令。要使用它们,内核将提供一个虚拟的动态共享对象(vDSO;它就像一个共享库,但仅在内存中),并带有一个函数,您可以使用该函数调用该函数,以使用硬件可用的最佳方法进行系统调用。它还提供了可用的特殊功能来获取当前时间,而无需进行系统调用以及其他一些操作。当然,如果您不使用动态链接器,则使用起来会有些困难。

还有另一种较旧的方法vsyscall,它与vDSO相似,但在固定地址使用单个页面。不建议使用此方法,如果您使用的是最新的内核,则会在系统日志上显示警告,甚至在更新的内核上也可以在启动时禁用该方法,以后可能会删除它。不要使用它。

关于linux - 系统调用的良好引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6905727/

有关linux - 系统调用的良好引用的更多相关文章

  1. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  6. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  10. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

随机推荐