扩展 GCC asm 中多个输入和输出操作数的正确用法是什么?

2024-02-28

在寄存器约束下,扩展 GCC asm 中的多个输入和输出操作数的正确使用是什么?考虑一下我的问题的最小版本。下面简要介绍 GCC、AT&T 语法的扩展 asm 代码:

    int input0 = 10;
    int input1 = 15;
    int output0 = 0;
    int output1 = 1;

    asm volatile("mov %[input0], %[output0]\t\n"
                 "mov %[input1], %[output1]\t\n"
                 : [output0] "=r" (output0), [output1] "=r" (output1)
                 : [input0] "r" (input0), [input1] "r" (input1)
                 :);

    printf("output0: %d\n", output0);
    printf("output1: %d\n", output1);

语法显示正确基于https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html然而,我一定是忽略了一些事情,或者犯了一些我因某种原因而看不到的小错误。

GCC 5.3.0 p1.0(无编译器参数)的输出为:

输出0:10
输出1:10

预期输出是:

输出0:10
输出1:15

在 GDB 中查看显示:

0x0000000000400581 :mov eax,DWORD PTR [rbp-0x10]
0x0000000000400584 :mov edx,DWORD PTR [rbp-0xc]
0x0000000000400587 : mov edx,eax
0x0000000000400589 : mov eax,edx
0x000000000040058b :mov DWORD PTR [rbp-0x8],edx
0x000000000040058e : mov DWORD PTR [rbp-0x4],eax

据我所见,它使用 input0 加载 eax,使用 input1 加载 edx。然后它用 eax 覆盖 edx,用 edx 覆盖 eax,使它们相等。然后将它们写回output0 和output1。

如果我对输出使用内存约束 (=m) 而不是寄存器约束 (=r),它会给出预期的输出,并且程序集看起来更合理。


问题是 GCC 假定所有输出操作数仅在指令末尾、所有输入操作数都已消耗之后写入。这意味着它可以使用相同的操作数(例如寄存器)作为输入操作数和输出操作数,这就是这里发生的情况。解决办法是标记[output0]早期破坏约束 https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html这样 GCC 就知道它是在 asm 语句结束之前写入的。

例如:

 asm volatile("mov %[input0], %[output0]\t\n"
              "mov %[input1], %[output1]\t\n"
              : [output0] "=&r" (output0), [output1] "=r" (output1)
              : [input0] "r" (input0), [input1] "r" (input1)
              :);

你不需要标记[output1]作为早期的破坏者,因为它只在指令末尾写入,所以它是否使用与以下相同的寄存器并不重要[input0] or [input1].

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

扩展 GCC asm 中多个输入和输出操作数的正确用法是什么? 的相关文章

  • 使用 gcc 的中间 GIMPLE 格式

    根据本文 http en wikipedia org wiki Intermediate languagegcc 在生成代码之前使用多种中间格式 我读到 GIMPLE 格式使用三个地址代码 这似乎是最容易使用的中间语言 但我需要更多细节 因
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • C 中类似函数的宏定义

    我想定义一个像 MACRO 这样的函数 IE define foo x if x gt 32 x else 2 x endif 那是 if x gt 32 then foo x present x else foo x present 2
  • typeof() 表达式内的副作用

    在 GNUC C 中 您可以使用typeof expression 并且使用内部带有副作用的表达式是合法的 例如 您可以使用以下 C 代码 int x 0 typeof x y 在这种情况下 副作用被忽略 并且 x 之后仍然为零 这是有道理
  • GCC 对潜在有效的代码抛出 init-list-lifetime 警告?

    我在 Debian不稳定的GCC 9 3 0上运行 我从事的一个项目最近发生了变化 引入了类似于下面的代码 include
  • `printf()` 中格式说明符“%qd”的用途是什么?

    我看到格式说明符 qd浏览时github https github com Microsoft clang blob master test Sema format strings c代码 然后我检查了 GCC 编译器 它工作正常 incl
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 公共基类打破了元组的空基类优化

    gcc 4 7 1 对元组进行空基类优化 我认为这是一个非常有用的功能 然而 这似乎有一个意想不到的限制 include
  • 如何在 Debian 上编译 DOS 程序?

    在我的汇编语言课程中 我们使用 DPMI 编写 DOS 程序 不幸的是 我无法一直使用 32 位 Windows 机器 我在我使用的几乎每台计算机上都安装了 Debian 虚拟机 我已经安装了 DOSBox 和 DOSEMU 有什么办法可以
  • “mov (%ebx,%eax,4),%eax”如何工作? [复制]

    这个问题在这里已经有答案了 一直在从事装配作业 并且在很大程度上我对装配非常了解 或者至少对于这项任务来说足够好 但这个 mov 的声明让我很困惑 如果有人能解释这个 mov 语句如何操作寄存器值 我将非常感激 mov ebx eax 4
  • Gcc 4.2 版本缺失

    在我的带有 osx lion 和 XCode 4 1 的新 macbook pro 上 我遇到了一些 gcc 问题 In usr bin我找不到gcc 4 2 我只有以下版本 i686 apple darwin11 llvm gcc 4 2
  • 什么定义了类型的大小?

    ISO C 标准规定 sizeof char lt sizeof short lt sizeof int lt sizeof long 我在 BIT Linux mint 19 1 上使用 GCC 8 大小为long int is 8 我正
  • CPU寄存器和多任务处理

    我目前正在学习汇编 我很困惑 CPU 寄存器如何与多任务一起工作 所以在多任务系统中 CPU可以随时暂停某个程序的执行并运行另一个程序 那么在这一步中寄存器值是如何保存的呢 寄存器是压入堆栈还是以其他方式 CPU 寄存器如何与多任务一起工作
  • 错误:“uint16_t”未声明? [复制]

    这个问题在这里已经有答案了 我有代码 include
  • INT_MIN % -1 是否会产生未定义的行为?

    gcc 生成浮动代码 引发SIGFPE对于以下代码 include
  • gcc 中 -g 选项的作用是什么

    我看到很多关于 gdb 的教程要求在编译 c 程序时使用 g 选项 我无法理解 g 选项的实际作用 它使编译器将调试信息添加到生成的二进制文件中 此信息允许调试器将代码中的指令与源代码文件和行号相关联 拥有调试符号可以使某些类型的调试 例如
  • 如何在程序中将自己缝合到自己的尾部,无限循环地封装 64KB 代码段?

    如果指令的顺序执行经过偏移量 65535 则8086将从同一代码段中的偏移量 0 处获取下一个指令字节 接下来的 COM 程序利用这一事实 不断将其整个代码 总共 32 个字节 缝合到自己的尾部 环绕在 64KB 代码段中 你可以称之为二元
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c

随机推荐

  • 需要 python lxml 语法帮助来解析 html

    我是 python 的新手 我需要一些有关使用 lxml 查找和迭代 html 标签的语法的帮助 以下是我正在处理的用例 HTML 文件的格式相当好 但并不完美 屏幕上有多个表格 其中一个包含一组搜索结果 每个表格包含页眉和页脚 每个结果行
  • 每天第一次调用网络服务很慢

    在构建此 Web 服务和调用它的应用程序时 我们注意到每天对该 Web 服务的第一次调用非常慢 有时甚至会超时 然而 此后的每一次通话都效果很好 有人能解释一下为什么会这样以及我们如何摆脱这种痛苦吗 提前致谢 如果是 ASP NET Web
  • 更改seaborn箱线图线彩虹颜色

    I found this beautiful graph online apparently made with plotly and wanted to recreate it with seaborn 到目前为止 这是我的代码 impo
  • AngularJS 实现模板本地化

    我想实现视图的本地化 也应该包括正文 我之前通过加载 JSON 文件并通过键进行迭代来完成此操作 键是类名 比我简单地将键的值分配给 元素与类 语言文件 JSON Header Title My Title Header Text Lore
  • Jersey 2 + HK2 - @ApplicationScoped 不工作

    我有课 ApplicationScoped public class Service private Map
  • (bool) 可靠地转换为 0 或 1 吗? [复制]

    这个问题在这里已经有答案了 来自一些reading https stackoverflow com questions 6627178 c99 why are false and true defined as 0 and 1 and no
  • iOS 中可用的路径目录

    NSSearchPathDirectory 这些常量指定各种目录的位置 enum NSApplicationDirectory 1 NSDemoApplicationDirectory NSDeveloperApplicationDirec
  • 将Angular2项目集成到Tomcat服务器中

    我为我的项目开发了一个 Spring maven Rest api 对于客户端 我使用 Angular2 和 typescript 作为 Angular 的新手 参考 Angular 网站进行开发 使用 npm 和 lite server
  • C# Winform 网格渲染在 Windows 7 上缓慢

    我注意到 C winform datagrid 在我的 windows 7 64 位机器上非常慢 对于具有 1000 行 足够的列 文本以适合屏幕宽度的标准网格 我看到滚动时出现明显的渲染延迟 即滚动 滚动条移动滞后约 0 5 秒而不是平滑
  • 当超过 6 个参数时 Observable.forkJoin 返回错误类型

    我遇到 Observable forkJoin 的问题 它推断出错误的返回类型 然后在传递超过 6 个参数时导致错误 Observable forkJoin service getType1 service getType2 service
  • 如何在 shell 脚本中即时解释变量?

    我正在使用 JQ 在 shell 脚本中读取 JSON 在这里 我无法动态解释 shell 脚本中的变量 HOME HOST PEMFILE JSON 文件 script install HOME lib install sh HOST P
  • 新的默认VB.NET项目立即报错

    我刚刚在 Mac 上安装了 Mono 版本 2 10 8 和 MonoDevelop 2 8 6 5 当我创建一个新项目 文件 gt 新解决方案 gt VBNet gt ASP NET gt Web 应用程序 时 创建后出现错误 尝试加载项
  • C 函数 fwrite() 不写入文件

    我正在尝试编写结构tempGroupFile into GroupFile fwrite 写入时返回1 但实际上文件中没有写入数据GroupFile 功能printRec 在屏幕上打印出结构 data是结构变量 文件GroupFile这些操
  • Android 上的 HTML5

    根据 http developer android com sdk android 2 0 highlights html http developer android com sdk android 2 0 highlights html
  • 如何在关闭钩子中获取返回码

    我需要根据我的应用程序结果修改JVM返回代码 但显式调用 System exit code 是有风险的 因为应用程序很复杂 并且很难识别正在运行的线程的结束 所以我想出了在 JVM 退出之前使用 shutdown hook 来修改返回代码
  • 无法将 tomsfastmath 链接到 libtomcrypt

    我正在用 c 编写一个安全的即时消息程序 使用 libtomcrypt C 库来实现 RSA 和 SPRNG 函数 我将 libtomcrypt 编译为静态库 并且能够链接到它并运行 sprng 函数并查看和使用它生成的随机数据 我遇到的问
  • RenderFlex 溢出错误仅出现在小部件测试中,如果我运行应用程序,一切正常

    可以在这里找到一个最小的可重现示例 https github com HerrNiklasRaab repro widget test overflow https github com HerrNiklasRaab repro widge
  • EGit:发出快进拉取 ~ 如何在 EGit 中为远程存储库配置 fetch

    那么让我来设置我的场景 我在 Spring Tool Suite Eclipse 4 5 1 中使用 EGit 4 1 1 我和精通技术的同事从远程 URL 克隆了相同的 git 存储库 我的精通技术的同事更喜欢命令行 他使用 VIM 修改
  • 使用 Jena 解析 RDF 递归

    我正在尝试使用 Apache Jena 递归解析 RDF 文档 它由如下数据集组成
  • 扩展 GCC asm 中多个输入和输出操作数的正确用法是什么?

    在寄存器约束下 扩展 GCC asm 中的多个输入和输出操作数的正确使用是什么 考虑一下我的问题的最小版本 下面简要介绍 GCC AT T 语法的扩展 asm 代码 int input0 10 int input1 15 int outpu