【问题标题】:Using inline assembly to swap two integer variables使用内联汇编交换两个整数变量
【发布时间】:2017-08-31 04:15:48
【问题描述】:

(编者注:这是一个调试问题,关于这个尝试的实现有什么问题(几乎所有内容),因此不是 How to write a short block of inline gnu extended assembly to swap the values of two integer variables? 的重复,但是如果你想要一个工作示例,请参阅 Q&A 和 https://stackoverflow.com/tags/inline-assembly/info。)


我正在尝试使用 gnu 扩展程序集交换两个整数变量,这就是我现在所拥有的:

int main()
{
    int a = 2;
    int b = 1;
    printf("a is %d, b is %d\n", a, b);
    // TODO (student): swap a and b using inline assembly
    printf("a is %d, b is %d\n", a, b);
    asm ("mov ebx, b;"
        "mov ecx, b;"
        "mov c, ecx;"
        "mov d, ebx;"
    );

我收到错误消息:asmPractice.c:17: Error: too many memory references for mov

我该如何解决这个问题?

【问题讨论】:

  • 您可以在 x86 上使用XCHG 指令进行交换。
  • 似乎有人在这个 SO 问题上做了同样的任务。 stackoverflow.com/q/45910530/3857942 。您不能以可靠(或根本)的方式使用变量名。您必须使用扩展内联通过约束传递参数。另一个 SO 问题的答案应该让您知道为什么应该避免使用 GNU 内联汇编,除非您知道自己在做什么。如果使用 AT&T 语法,则操作数与 Intel 语法相反。
  • @AnttiHaapala :它被标记为 GNU 和 C(以及 GNU 程序集),因此至少可以假设 GCC。组装说明建议的平台似乎是 x86。
  • @MichaelPetch 啊,这是真的。

标签: c gcc gnu inline-assembly


【解决方案1】:

使用扩展的内联汇编语法,这是一个单行:

volatile int a = 1;
volatile int b = 2;

asm("" : "=r" (a), "=r" (b) : "0" (b), "1" (a) : );
//      ^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
//           input               output

printf("a is %d, b is %d\n", a, b);

【讨论】:

    【解决方案2】:

    不知道这是否重要。但在我的记忆中,您需要在注册调用之前输入%,以便让翻译理解您所说的注册。 赞mov %esp, %ebp

    尝试一下,但不是 100% 肯定会解决它。 asm in C "too many memory references for `mov'"参考这篇文章

    【讨论】:

    • 我之前尝试过,但它给出了错误:/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a when search对于-lgcc /usr/bin/ld: 找不到-lgcc
    • @WendiZhang 这是正确的更正,现在是另一个问题。
    • @WendiZhang :如果你在没有 gcc-multilib 包的 64 位 linux 上编译,你会得到这个错误。如果您使用的是 Ubuntu(或基于 ubuntu 的发行版),您可以尝试 sudo apt install gcc-multilib 或 Debian apt install gcc-multilib。然后使用gcc-m32 选项进行编译。
    【解决方案3】:

    尝试在注册前放双 %。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多