gcc内联汇编错误"mov的操作数类型不匹配"

use*_*906 1 c assembly gcc inline-assembly

//quick inline asm statements performing the swap_byte for key_scheduling
inline void swap_byte(unsigned char *x, unsigned char *y)
{
 unsigned char t;
 asm("movl %1, %%eax;"
     "movl %%eax, %0;"
     :"=r"(t)
     :"r"(*x)
     :"%eax");
 asm("movl %1, %%eax;"
     "movl %%eax, %0;"
     :"=r"(*x)
     :"r"(*y)
     :"%eax");
 asm("movl %1, %%eax;"
     "movl %%eax, %0;"
     :"=r"(*y)
     :"r"(t)
     :"%eax");       
}
Run Code Online (Sandbox Code Playgroud)

在这里,我想从交换焦炭x和存储y,与同为yx.我已经通过更改movl来编译这些指令mov但没有成功.编译/链接的问题在哪里?

这是cygwin中编译的输出:

$ gcc rc4_main.c -o rc4ex
/tmp/ccy0wo6H.s: Assembler messages:
/tmp/ccy0wo6H.s:18: Error: operand type mismatch for `mov'
/tmp/ccy0wo6H.s:18: Error: operand type mismatch for `mov'
/tmp/ccy0wo6H.s:26: Error: operand type mismatch for `mov'
/tmp/ccy0wo6H.s:26: Error: operand type mismatch for `mov'
/tmp/ccy0wo6H.s:34: Error: operand type mismatch for `mov'
/tmp/ccy0wo6H.s:34: Error: operand type mismatch for `mov'
Run Code Online (Sandbox Code Playgroud)

Dav*_*erd 6

为了简化它(比用户35443):

asm("" : "=r" (*x), "=r" (*y) : "1" (*x), "0" (*y));
Run Code Online (Sandbox Code Playgroud)

看马!没有代码!是的,这确实有效.

解释这是如何工作的:

当编译器构建代码时,它会跟踪每个寄存器中的值.所以,如果有这些输入到asm:

"r"(*x),"r"(*y)

编译器将选择一个寄存器并将*x放入其中,然后选择一个寄存器并将*y放入其中,然后调用您的asm.但它也跟踪哪个变量在哪个寄存器中.如果只是某种方式告诉编译器所有它必须做的就是开始将两个寄存器视为相反的变量,那么我们将被设置.这就是这段代码的作用:

  1. 说"= r"(*x)意味着我们将覆盖*x中的值,即我们将该值放入寄存器中.
  2. 说"0"(*y)意味着在输入到asm时,编译器必须将*y的值放入与输出参数#0使用的寄存器相同的寄存器中.

因此,在不使用任何实际汇编指令的情况下,我们告诉编译器交换这两个值.

我们不会"免费"获得这个,因为编译器必须在调用asm之前将值加载到寄存器中.但是,无论如何都要发生这种情况......

实际更新内存怎么样?编译器将(如有必要)将寄存器中的这些值写回内存.因为它知道哪个变量在哪个寄存器中,所有变量都按预期工作.