system V ABI

2024-01-22 08:59
文章标签 system abi

本文主要是介绍system V ABI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

system V ABI

译自 system V ABI

System V应用程序二进制接口是一组规范,详细说明了调用约定,目标文件格式,可执行文件格式,动态链接语义,以及符合X / Open通用应用程序环境规范和System V接口定义的系统的更多规范。现在,它已成为主要的Unix操作系统(例如Linux,BSD系统和许多其他操作系统)使用的标准ABI。 可执行和可链接格式(ELF)是System V ABI的一部分。

ABI被组织为可移植的基础文档和针对特定平台的补充。 由于格式已适应新平台(例如X86-64),因此已经发布了非官方的新体系结构处理器补充。 该标准是可扩展的,并且格式随着Unix供应商添加新功能而不断发展。 由于存在许多非官方的补充规范以及Unix操作系统的混乱历史,当前的情况是System V ABI已成为一系列非官方的草案规范,而没有真正的中央管理机构。

许多高级功能(例如动态链接)是可选的,并且加载简单的静态链接的ELF程序非常简单。 该标准的早期版本更加雄心勃勃,并试图标准化软件包安装格式和X11详细信息,而今天已经忽略了这些过时的详细信息。 常见的操作系统开发工具(例如Binutils和GCC)对ABI有很好的支持。 诸如i686-elf-gcc之类的工具链会根据此ABI生成代码和可执行文件。

可执行和可链接格式

可执行和可链接格式在System V ABI中被标准化为可修改的文件格式。处理器补充通过声明ELF格式结构中使用的抽象类型的大小以及字节序,可以巧妙地更改文件格式。 这使框架文件格式适用于多种处理器体系结构,其中通过简单地增加各种标头字段的大小来处理32位和64位系统之间的差异。 该格式足够强大,可以包含辅助信息,例如调试信息,动态库的重定位以及其他特定于供应商的其他信息。 这允许对目标文件和链接的可执行文件使用相同的格式。

调用约定
这是System V ABI主要体系结构的重要调用约定详细信息的简短描述。 所列出的信息并不完整,您应查阅相关的处理器补充文件(psABI)以了解详细信息。 此外,您可以使用编译器的-S选项在调用汇编器之前停止编译过程,这使您可以研究编译器如何按照相关的调用约定将代码转换为汇编。

  • i 386
    这是一个32位平台。 堆栈向下生长。 函数的参数以相反的顺序传递到堆栈上,以便第一个参数是被压入堆栈的最后一个值,然后将成为堆栈上的最小值(译注:这里的值指地址)。 可以通过修改被调函数的参数来修改在堆栈上传递的参数。 使用call指令来调用函数,该指令将下一条指令的地址压入堆栈并跳转到操作数。 函数使用ret指令返回调用者,该指令从堆栈中弹出一个值并跳转到该值。 在调用call指令之前,堆栈是16字节对齐的。

    函数保留寄存器ebxesiediebpesp; 而eaxecxedx是暂存器。 返回值存储在eax寄存器中,或者如果返回值是64位的,则高32位进入edx,低32位进入eax。 被调函数将ebp推入堆栈,这样紧挨着主调函数栈帧的栈顶,即此时caller-return-eip位于ebp上方4个字节处,然后将ebp设置为已保存ebp的地址。 这允许遍历现有堆栈帧。 通过指定-fomit-frame-pointer GCC选项可以消除此问题。

    作为特殊的例外,GCC假定堆栈未正确对齐,并在输入main或在函数上设置了属性((force_align_arg_pointer))时将其重新对齐。

  • x86-64
    这是一个64位平台。 堆栈向下生长。 函数的参数在寄存器rdi,rsi,rdx,rcx,r8,r9中传递,并且其他值以相反的顺序在堆栈中传递。译注前6个从左到右依次放入rdi,rsi,rdx,rcx,r8,r9超出6个的参数从右向左放入栈中。可以通过修改被调用函数的参数来修改在堆栈上传递的参数。 使用call指令来调用函数,该指令将下一条指令的地址压入堆栈并跳转到操作数。 被调函数使用ret指令返回调用者,该指令从堆栈中弹出一个值并跳转到该值。 在调用调用指令之前,堆栈是16字节对齐的。

    函数保留寄存器rbxrsprbpr12r13r14r15raxrdirsirdxrcxr8r9r10r11是暂存寄存器。 返回值存储在rax寄存器中,或者如果它是128位值,则高64位进入rdx。 可选地,被调函数推入rbp,以使caller-return-rip在其上方8个字节,并将rbp设置为已保存的rbp的地址。 这允许遍历现有堆栈帧。 通过指定-fomit-frame-pointer GCC选项可以消除此问题。

    信号处理程序在同一堆栈上执行,但是在将任何内容压入堆栈之前,会从堆栈中减去称为红色区域的128个字节。 这允许小的叶子函数使用128字节的堆栈空间,而无需通过从堆栈指针中减去来保留堆栈空间。 众所周知,红色区域会给x86-64内核开发人员造成问题,因为在调用中断处理程序时,CPU本身并不尊重红色区域。 由于ABI与CPU行为相矛盾,这会导致微妙的内核损坏。 解决方案是使用-mno-red-zone或通过在内核模式下在当前堆栈以外的其他堆栈上处理中断来构建所有内核代码(从而实现ABI)。

叶子函数参考

  • Handling Leaf Functions
  • 叶和非叶

在这里插入图片描述

这篇关于system V ABI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/632496

相关文章

CS162 Operating System-lecture2

A tread is suspended or no longer executing when its state’s not loaded in registers the point states is pointed at some other thread .so the thread that’s suspended is actually siting in memory and

在WinCE的C#编程中,需要静态调用C++的动态库,需要添加using System.Runtime.InteropServices

using System.Runtime.InteropServices;         [DllImport("Win32DLL.dll", EntryPoint = "WriteREG_SZToRegTCHAR")]         private static extern bool WriteREG_SZToRegTCHAR(int iFlag, string regKeyP

c语言使用system函数后台运行python脚本

最近需要在c工程的mian函数中使用system函数调用一个shell脚本,shell脚本是用来将某些系统配置通过sock通信发送给主核进程,但是可能出现偶发性的配置失败情况,经过分析可以大概断定是由于sock通信的时候,主核进程正在忙于其他事物导致未能在expire之前将消息接受并处理,导致消息丢失,而发送方无法感知系统是否成功加载配置。         所以,需要在脚本的最后

java system.in问题

public static final InputStream in system关于in属性的定义InputStream是一个抽象类。抽象类本身是没有对象的,怎么可能用IN 属性调用reaad()方法?system.in.read();方法的解释 我想具体的知道是怎么得到这个 InputStream对象的。system方法中并没有给出定义。既然IN对象没有创建,有怎么可能调用IN方法?说起

JSP中System.out.println()与out.println()区别

out.println()输出到客户端。   在out.println()中,out是response的实例,是以response为对象进行流输出的,即将内容输出到客户端。如果在JSP页面中使用System.out.println(),在客户端只会输出一个空格。System.out.println()打印在控制台当中。    System.out.println()用的是标准输出流,这个是输出在

获取时间戳是使用System.currentTimeMillis()还是使用new Date().getTime()(阿里开发规范)?

1.阿里规范 在阿里的Java开发手册中强制要求使用System.currentTimeMillis() 2.为什么(源码详解) new Date().getTime()它实际上也是调用的System.currentTimeMillis(),源码分析。 这个fastTime是它的成员变量,在new Date()的时候就被赋值了。 扩展一下这个transient这个关键字,它是为了保护

80端口被NT kernel System占用

 前段时间停止了Apache,结果在打开的时候发现无法打开,80端口被占用,于是win+r 运行cmd 输入netstat -ano 可以看到80端口被PID4占用,于是打开任务管理器-进程-查看,选择列,勾选PID 可以看到pid 4 的被NT kernel & System 占用

多线程环境下 System.out.println 导致死锁问题分析

背景 一个文件采集系统,使用了多线程递归采集指定目录下的文件,并为每个目录创建一个线程去采集。 这个应用每隔几天就出现罢工情况,查看进程还在,堆内存空间还很充足,就是导出堆栈时,发现几乎所有的采集线程都处于 BLOCKED 状态了: "thread/dir/1718963987160" #82581 prio=5 os_prio=0 tid=0x00007f498c109000 nid=0x

Oracle数据库中scott登录失败,sys和system用户,以及normal 、sysdba、 sysoper权限

目录 1 scott用户模式 1.1 scott登录不上 1.2 模式与模式对象 1.3 实例模式SCOTT 2 sys和system用户的区别 3 normal 、sysdba、 sysoper有什么区别 1 scott用户模式 1.1 scott登录不上 scott用户使用SYSDBA可以登录,但是使用NORMAL不可以登录 解决方法~ 第一步:提示 account

System.Runtime, Version=6.0.0.0,生成的dll使用出现错误问题

解决: 1.unity左上角file点击选中build settings 点击player settings ,然后在player的window的other settings的configuration更改为 Framerwork 其实这个不换也可以的,我后面调试完,发现这个不是重点,下面第2点才是重点 2.然后vscode创建项目确保为framework 版本默认即可,如果选择sta