0..9 约束在 GCC 内联汇编中起什么作用?

2023-11-30

手册 says:

允许使用与指定操作数编号匹配的操作数。如果一个数字 在同一个选项中与字母一起使用,数字应该放在最后。

我不确定这意味着什么。

示例代码:

asm volatile("swap %0" : "=r" (value) : "0" (value));

(堆栈溢出的内联汇编标签 wiki有其他文档和指南的链接)


这就像一种分割方式"+r"(value)将输入/输出操作数转换为单独的操作数(具有单独的 C 变量)以用于输入和输出,同时仍然强制它们选择相同的寄存器。

具体来说"0"表示“在与操作数 0 相同的寄存器中输入操作数”,在本例中为"=r"(value)。所以无论注册什么%0 picks, %1将是相同的寄存器。操作数从左到右计数,从0.操作数的编号相同%0, %1当匹配约束引用较早的操作数时,asm 模板中的 等适用。

我只见过它与匹配输出约束的输入约束一起使用。这使您可以从模板中省略它,而不会有编译器期望您的 asm 模板从一个寄存器复制到另一个寄存器的风险。

对输入和输出使用相同的 C 变量更容易"+r"(value).对此的匹配约束是毫无意义的复杂性。

Maybe "+r"仅在更高版本的 gcc 中添加,因为您确实会看到当读/写操作数更容易时使用匹配约束。

如果在同一个选项中数字与字母一起使用,则数字应放在最后。”

这是考虑给编译器提供多个约束选择的约束的可能性。例如"rm"让编译器选择寄存器或内存。

"a0"在 x86 上会选择 EAX 或相同的寄存器作为操作数0。我不确定什么时候会有用。也许它可以与早期破坏器一起使用,告诉编译器该输入与某个输出位于同一寄存器中仍然可以吗?但可选任何寄存器,例如"r0"?

显然如果你使用像这样的约束"r0"你(通常)需要明确使用%1(或者它具有的任何数字或命名操作数)位于 asm 模板中,因为您不知道编译器将在给定周围代码和优化级别的情况下选择哪个位置。


调试约束时,使用包含约束的 asm 注释会很有用,包括您要做出假设的内容。

asm ("swap %0    # other operand: %1  "  : "=r"(output) : "0"(input));

生成的 asm 将打印相同的寄存器名称两次%0 and %1。这个案例很简单;在更复杂的情况下它会变得更有趣。

就像如果你用过"r"(input),您的代码可能会正常工作,因为编译器确实为输入和输出选择了相同的reg(因为没有早期破坏)。但是当它因为选择了不同的规则而崩溃时output(并期望原始值input仍然在其寄存器中不变),您可以通过查看约束选择的寄存器来调试它,然后意识到您假设它们会选择相同的寄存器但没有告诉编译器。

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

0..9 约束在 GCC 内联汇编中起什么作用? 的相关文章

  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 当其源是 https uri 时如何使 wpf MediaElement 播放

    在 wpf 独立应用程序 exe 中 我在主窗口中包含了 MediaElement
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • 如何使用 C# 以编程方式编辑 Power BI Desktop 文档参数或数据源?

    我有一个在 Power BI Desktop 中内置的报告模板 并保存为 pbix 或 pbit 文件 该模板使用DirectQuery SQL数据库作为数据源 而服务器地址和数据库名称被提取到参数中 还有一个参数包含一个ReportId
  • 为什么在 C++ 中声明枚举时使用 typedef?

    我已经很多年没有写过任何 C 了 现在我正试图重新开始 然后我遇到了这个并考虑放弃 typedef enum TokenType blah1 0x00000000 blah2 0X01000000 blah3 0X02000000 Toke
  • C# Outlook 从收件人获取 CompanyName 属性

    我目前正在使用 C 编写 Outlook 2010 AddIn 我想要的是从我从 AppointmentItem 中提取的 Recipient 对象中获取 CompanyName 属性 因此 有了 AppointmentItem 的收件人
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 为什么 C# 中同一类型的隐式和显式运算符不能共存? [复制]

    这个问题在这里已经有答案了 为什么同一类中两个相同类型的运算符 显式和隐式 不能共存 假设我有以下内容 public class Fahrenheit public float Degrees get set public Fahrenhe
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 为什么 std::function 不是有效的模板参数,而函数指针却是?

    我已经定义了名为的类模板CallBackAtInit其唯一目的是在初始化时调用函数 构造函数 该函数在模板参数中指定 问题是模板不接受std function作为参数 但它们接受函数指针 为什么 这是我的代码 include
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?

    我试图理解图形 在 Graphics FromImage 文档中 它有这样的示例 private void FromImageImage PaintEventArgs e Create image Image imageFile Image
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 在 Qt 中播放通知(频率 x)声音 - 最简单的方法?

    Qt 5 1 或更高版本 我需要播放频率为 x 的通知声音 n 毫秒 如果我能像这样组合音调那就太好了 1000Hz 持续 2 秒 然后 3000Hz 持续 1 秒 最简单的方法是使用文件 WAV MP3 例如如此处所述 如何用Qt播放声音
  • 如何调用与现有方法同名的扩展方法? [复制]

    这个问题在这里已经有答案了 我有这样的代码 public class TestA public string ColA get set public string ColB get set public string ColC get se
  • 当 Verb="runas" 时设置 ProcessStartInfo.EnvironmentVariables

    我正在开发一个 C 应用程序 我需要创建变量并将其传递给新进程 我正在使用ProcessStartInfo EnvironmentVariables 新进程必须提升运行 因此我使用 Verb runas var startInfo new
  • 如何知道 HTTP 请求标头值是否存在

    我确信这很简单 但是却让我感到厌烦 我在 Web 应用程序中使用了一个组件 它在 Web 请求期间通过添加标头 XYZComponent true 来标识自身 我遇到的问题是 如何在视图中检查此组件 以下内容不起作用 if Request

随机推荐