当前位置: 首页 > 知识库问答 >
问题:

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

蒋骏
2023-03-14

在寄存器约束下的扩展GCC ash中正确使用多个输入和输出操作数是什么?考虑我的问题的最小版本。以下是GCC、AT中的简短扩展ash代码

    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语法似乎是正确的,但是,我一定忽略了什么,或者犯了一些我出于某种原因看不到的微不足道的错误。

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

输出0:10
输出1:10

预期输出为:

输出0:10输出1:15

在GDB中查看它显示:

0x0000000000400581

从我所看到的,它用input0加载eax,用input1加载edx。然后用eax覆盖edx,用edx覆盖eax,使两者相等。然后将其写回output0和output1。

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

共有1个答案

赫连棋
2023-03-14

问题是GCC假设所有输出操作数仅在指令末尾写入,在所有输入操作数都被消耗之后。这意味着它可以使用相同的操作数(例如寄存器)作为输入操作数和输出操作数,这就是这里发生的情况。解决方案是使用早期的clobber约束标记[output0],以便GCC知道它在ami语句结束之前写入。

例如:

 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]标记为早期Clobber,因为它只在指令末尾写入,因此它是否使用与[input0][input1]相同的寄存器并不重要。

 类似资料:
  • 我想直接使用多步骤输入,例如用户选择F1-并开始步骤选择项目。 目前我找到了下面的示例,并删除了quickOpen和basic输入 https://github.com/microsoft/vscode-extension-samples/blob/master/quickinput-sample/src/extension.ts 我不想从这个开始 我想从这个开始当用户使用F1

  • 主要内容:C++输入流和输出流本教程一开始就提到,C++ 又可以称为“带类的 C”,即可以理解为 C++ 是 C 语言的基础上增加了面向对象(类和对象)。在此基础上,学过 C 语言的读者应该知道,它有一整套完成数据读写(I/O)的解决方案: 使用 scanf()、gets() 等函数从键盘读取数据,使用 printf()、puts() 等函数向屏幕上输出数据; 使用 fscanf()、fgets() 等函数读取文件中的数据,使

  • 本文向大家介绍使用UITextField限制输入金额是正确小数,包括了使用UITextField限制输入金额是正确小数的使用技巧和注意事项,需要的朋友参考一下 要判断输入金额为正确金额的方法有两个,一个是用正则表达式,另一个就是用textfield的代理方法 有时候难免遇到这样的需求,不符合规则的金额就不让输入时,那用这种方法比较合理 如果设置输入键盘为Decimal Pad时,输入为数字和小数点

  • 问题陈述:根据问题,有一个二叉树,其根节点3左子节点9,右子节点20,当20作为根节点时,其左子节点15,右子节点7。9没有孩子。所以结构看起来[3,9,20,null,null,15,7]。 在此二叉树中查找级别顺序遍历。水平顺序遍历/宽度优先搜索 输出:[ [3], [9,20], [15,7] ] 为了实现这个方法,我创建了一个树结构,如 我还创建了另一个类,返回这个输出列表 主要功能出现困

  • 输出 用print加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下: >>> print 'hello, world' print语句也可以跟上多个字符串,用逗号“,”隔开,就可以连成一串输出: >>> print 'The quick brown fox', 'jumps over', 'the lazy dog' The quick brown

  • 输出 用print()在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下: >>> print('hello, world') print()函数也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出: >>> print('The quick brown fox', 'jumps over', 'the lazy dog') The qu