为什么我们需要在内联汇编中修改寄存器列表?

2023-12-07

我的指南书中写道:

在内联汇编中,Clobered 寄存器列表用于告诉 我们正在使用的寄存器的编译器(因此它可以在之前清空它们) 那)。

我完全不明白,为什么编译器需要知道这一点?保留这些寄存器有什么问题?他们的意思是备份它们并在汇编代码之后恢复它们吗?

希望有人能提供一个例子,因为我花了几个小时阅读有关 Clobbered 寄存器列表的内容,但没有解决这个问题的明确答案。


The problems you'd see from failing to tell the compiler about registers you modify would be exactly the same as if you wrote a function in asm that modified some call-preserved registers1. See more explanation and a partial example in Why should certain registers be saved? What could go wrong if not?

在 GNU 内联汇编中,all假定保留寄存器,编译器选择的寄存器除外"=r" / "+r"或其他输出操作数。编译器可能会在任何寄存器中保留一个循环计数器,或者稍后要读取的任何其他内容,并期望它仍然具有在来自 asm 模板的指令之前放置的值。 (禁用优化后,编译器不会跨语句将变量保留在寄存器中,但当您使用-O1或更高。)

除了属于某个内存的一部分的位置之外,所有内存都相同"=m" or "+m"内存输出操作数。 (除非你使用"memory"破坏。)参见如何指示可以使用内联 ASM 参数*指向*的内存?更多细节。

脚注1:
与函数不同,您应该not使用您自己的指令在 asm 模板中保存/恢复任何寄存器。只需告诉编译器它就可以保存/恢复在整个函数的开始/结束处内联后,并避免在其中包含任何需要的值。事实上,在具有红色区域的 ABI(如 x86-64 System V)中,使用push/pop在 asm 内部将具有破坏性:在 C++ 内联汇编中使用基址指针寄存器


GNU C inline asm 的设计理念是它使用与编译器内部机器描述文件相同的语法。标准用例是用于包装single指令,这就是为什么如果模板字符串中的 asm 代码在写入某些寄存器之前没有读取其所有输入,则需要早期破坏声明。

模板对于编译器来说是一个黑匣子;您需要向优化编译器准确地描述它。任何错误实际上都是未定义的行为,并且为编译器留下了混乱周围代码中其他变量的空间,甚至可能在调用此变量的函数中(如果您修改了编译器未使用的调用保留寄存器)。

这使得仅通过测试来验证正确性是不可能的。您无法区分“正确”和“恰好适用于周围的代码和编译器选项集”。这就是为什么您应该避免使用内联汇编的原因之一,除非好处大于缺点和错误风险。https://gcc.gnu.org/wiki/DontUseInlineAsm

GCC 只是对模板字符串进行字符串替换,非常类似于 printf,并将整个结果(包括编译器生成的纯 C 代码指令)作为单个文件发送到汇编器。看看https://godbolt.org/有时候;即使内联汇编中有无效指令,编译器本身也不会注意到。只有真正组装的时候才会出现问题。 (编译器浏览器站点上的“二进制”模式。)


也可以看看https://stackoverflow.com/tags/inline- assembly/info获取更多指南链接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我们需要在内联汇编中修改寄存器列表? 的相关文章

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查

随机推荐

  • 在 Docker 容器内使用 ldap

    我有 2 个 docker 容器 第一个 docker container 内部是我的 lamp 应用程序 其中包含 php 7 3 4 apache2 第二个里面是mysql数据库 我尝试连接第一个容器内的 LDAP 服务器 我继续进入
  • 复合 JTree 节点允许事件传递到下面的对象

    我正在尝试创建一个 JTree 其中一些节点是包含 JLabel 和 JButton 的复合对象 Node 代表 JLabel 显示的服务器和端口 JButton 将使用 Desktop API 打开默认浏览器并转到 URL 我已经阅读了以
  • 如何在 PHP 中减小图像大小而不损失质量 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我正在尝试开发一个基于图像的网站 我真的对更快的页面加载速度和最佳压缩实践的最佳图像类型感到困惑 请告诉我压缩图像大小的最佳方法 如果您希望使用编码本身来减少大小 您可以在 ph
  • 取消 UILocalNotification

    我的 UILocalNotification 有问题 我正在用我的方法安排通知 void sendNewNoteLocalReminder NSDate date alrt NSString title some code UILocalN
  • 在 JavaScript 中使用标签

    你能向我解释一下如何在与break交互的语句上使用标签 switch while do和for 请举例说明 通常 我看到它在突破到外循环 var i j dance for i 0 i lt 20 i for j 0 j lt 20 j c
  • 在 Pandas 中使用 read_csv 处理不需要的换行符

    我对从 SAP 导出的数据有疑问 有时您可以在发布文本中找到换行符 本来应该在一行中的内容却变成了两行 这会导致一个非常糟糕的数据框 最烦人的是 我无法让 pandas 意识到这个问题 它只是读取那些错误的行 即使列数小于标题 错误 dat
  • RAILS,捆绑安装返回 - 未定义符号:SSLv2_method [重复]

    这个问题在这里已经有答案了 可能的重复 未定义的符号 运行捆绑安装时的 SSLv2 method 我尝试 捆绑安装 我的 Rails 项目 但出现此错误 Fetching gem metadata from https rubygems o
  • 通用链接不适用于 WKWebView

    I have web view基于应用程序和公司中的其他本机应用程序 我们正在使用universal links在需要时将用户重定向到其他应用程序 其他应用程序仍然支持universal links 我可以通过按链接来运行它们Apple N
  • Rails 4 资产管道:来自 js 的 asset_path 中资产缺少指纹

    我正在部署一个 Rails 4 0 应用程序 其中包含 HTML 部分模板作为我们前端 JavaScript 框架的资产 尽管这些模板是资产管道的一部分并且已正确预编译 但当我调用asset path从我们的 js 文件中嵌入的 ruby
  • 在 Javascript 中,“d.setDate(d.getDate() + 1)”在时间更改的天数内给出错误答案

    我有以下代码 var d new Date 2016 03 27 console log d getDate d d setDate d getDate 1 console log d getDate d 这给出了错误的答案 27 Date
  • Parallel.Foreach 循环,与显式 throw 语句不一致的行为

    使用 Linqpad 创建了一个简单的程序 我在其中显式抛出异常Parallel Foreach循环 理想情况下应在调用者中捕获为Aggregate Exception 但是当我明确抛出异常时 它有时会随机跳过一些异常 我无法理解这种行为
  • 从 iPhone 上传视频文件到服务器

    我知道如何将图像上传到运行 PHP 的服务器 但我一直坚持上传视频 我用过这个建议上传我的视频文件 发帖方法都可以 我在服务器上得到的是一个0字节的文件 我的代码如下 void imagePickerController UIImagePi
  • Jupyter Notebook 中使用 cython 进行线路分析

    我正在尝试在 jupyter 笔记本中使用 liner profiler 库和 cython 函数 它只工作了一半 我得到的结果仅包含函数的第一行 没有分析结果 cython a cython linetrace True cython b
  • 在T-SQL中生成随机字符串[重复]

    这个问题在这里已经有答案了 可能的重复 使用 T SQL 生成随机字符串 我需要在触发器内生成一个带有字母和数字字符的随机字符串 该字符串的长度必须为 15 并且大写 有人有主意吗 这远非最佳解决方案 但它会按指定方式工作 select c
  • 从 PHP 内部进行 SFTP

    我正在构建一个 Web 应用程序 除了其他功能外 它还需要连接到 FTP 服务器来下载或上传文件 该应用程序是用 PHP 编写的 托管在 Linux 服务器上 我想知道是否也可以提供对 SFTP 服务器的支持 但在 Google 上快速搜索
  • 在 jQuery 中,当单选按钮都具有相同名称时,如何获取它们的值?

    这是我的代码 table tr td Sales Promotion td td td tr table
  • 通用列表属性的必需属性

    是否可以将 Required 属性放到 List 属性上 我绑定到 POST 上的通用列表 想知道如果属性中有 0 个项目 是否可以使 ModelState IsValid 失败 添加Required列表样式属性的属性并不能真正实现您想要的
  • 我尝试安装 React Native 并构建失败

    我尝试安装 React Native 但构建失败 为什么 Windows PowerShell 版权所有 C 微软公司 版权所有 尝试新的跨平台 PowerShellhttps aka ms pscore6 PS C Users stefa
  • Java RMI 中的代码库到底有什么意义?

    我目前正在学习 RMI 我不太理解代码库的概念 我读到的每篇论文都表明 调用远程对象的客户端可以从代码库加载方法定义 现在的问题是 我的类路径中是否不需要描述 接口 如果我只在运行时知道远程对象上的方法 我如何调用它们 这甚至无法编译 我完
  • 为什么我们需要在内联汇编中修改寄存器列表?

    我的指南书中写道 在内联汇编中 Clobered 寄存器列表用于告诉 我们正在使用的寄存器的编译器 因此它可以在之前清空它们 那 我完全不明白 为什么编译器需要知道这一点 保留这些寄存器有什么问题 他们的意思是备份它们并在汇编代码之后恢复它