微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么寄存器通过Linux x86-64函数调用保存

我相信我理解linux x86-64 ABI如何使用寄存器和堆栈将parameter passing给一个函数(参见之前的ABI讨论 )。 我感到困惑的是,如果/函数调用期望保留哪些寄存器。 也就是说,哪些寄存器是不被破坏的?

如何确定保存在堆栈中的值?

汇编代码在Windows 8 x64上

你可以直接在Windows中调用任务吗?

c ++使用裸函数

在没有堆栈的情况下在Linux上进行系统调用

以下是文档中的完整注册表及其使用方法[ PDF链接 ]:

r12 , r13 , r14 , r15 , rbx , rbx , rbp是被保存的寄存器 – 它们在“保留跨函数调用”列中有“是”。

ABI规定了一个符合标准的软件是可以期望的。 它主要是为编译器,连接器和其他语言处理软件的作者编写的。 这些作者希望他们的编译器生成能够与由相同(或不同)编译器编译的代码正常工作的代码。 他们都必须同意一套规则:从调用者传递给被调用者的函数的形式化参数如何,函数的返回值是如何从被调用者传回给调用者的,哪些寄存器在调用边界上被保留/暂存/未定义,等等上。

例如,一个规则指出,为函数生成的汇编代码必须在更改值之前保存保留的寄存器的值,并且代码必须在返回给调用者之前恢复保存的值。 对于暂存寄存器,生成代码不需要保存和恢复寄存器值; 如果需要的话可以这样做,但不允许符合标准的软件依赖于这种行为(如果它不符合标准的软件)。

如果您正在编写汇编代码,则有责任按照相同的规则进行播放(您正在扮演编译器的角色)。 也就是说,如果您的代码更改了一个被保存的被保存的寄存器,则您负责插入保存并恢复原始寄存器值的指令。 如果程序集代码调用外部函数,则代码必须以符合标准的方式传递参数,并且可以依赖于被调用程序返回时实际保留寄存器值的事实。

这些规则定义了符合标准的软件如何相处。 但是,编写(或生成遵循这些规则的代码是完全合法的! 编译器总是这样做,因为他们知道在某些情况下不需要遵循这些规则。

例如,考虑一个名为foo的C函数,声明如下:

static foo(int x);

在编译时,编译器100%确定这个函数只能被当前正在编译的文件中的其他代码调用函数foo不能被其他东西调用,因为静态的定义是什么意思。 由于编译器在编译时知道所有foo的调用者,所以编译器可以自由地使用它想要的任何调用序列(直到并包括根本不做任何调用,即将foo的代码内联到foo的调用者。

作为汇编代码的作者,你也可以这样做。 也就是说,只要协议不干涉或违反符合标准的软件的期望,就可以在两个或更多的例程之间实现“私人协议”。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐