gcc内联汇编错误“mov的操作数类型不匹配” [英] gcc inline assembly error "operand type mismatch for mov"

查看:456
本文介绍了gcc内联汇编错误“mov的操作数类型不匹配”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  //为key_scheduling执行swap_byte的快速内联asm语句
inline void swap_byte(unsigned char * x,unsigned char * y)
{
无符号字符;
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);

$ / code>

这里我试图从 x 并存储在 y 中,并且对于 y X
我已经通过将 movl 更改为 mov 来编译这些指令,但没有成功。

下面是在cygwin中编译的输出:

  $ gcc rc4_main.c -o rc4ex 
/tmp/ccy0wo6H.s:汇编信息:
/tmp/ccy0wo6H.s:18:错误:mov的操作数类型不匹配'
/tmp/ccy0wo6H.s:18:错误:'mov'的操作数类型不匹配
/tmp/ccy0wo6H.s:26:错误:'mov'的操作数类型不匹配
/ tmp / ccy0wo6H.s:26:错误:'mov'的操作数类型不匹配
/tmp/ccy0wo6H.s:34:错误:'mov'的操作数类型不匹配
/tmp/ccy0wo6H.s: 34:Error:mov'操作数类型不匹配


解决方案

  unsigned char t; 
asm(movl%1,%% eax;
movl %% eax,%0;
:= r(t)/ *< - here * /
:r(* x)/ *< - 这里是* /
:%eax);

您无法将某个值从32位寄存器移动到单字节内存位置。 t 位于堆栈中, x 位于其他位置,但两者都以相同方式访问。其他方面的问题类似。你应该只移动一个字节。



尝试这样的事情,但还有更多的方法可以做到这一点(我还没有尝试过,请看下面):

  unsigned char t; 
asm(movb%1,%% al\\\

movb %% al,%0\\\

:= r(t)
:r(* x)
:%al);
asm(movb%1,%% al\\\

movb %% al,%0\\\

:= r(* x)
:r(* y)
:%al);
asm(movb%1,%% al\\\

movb %% al,%0\\\

:= r(* y)
:r(t)
:%al);

整个过程可以简化为:


movb(%2),%% ah\\\

movb %% ah,(%1)\\\

movb %% al,(%2)\\\

:/ *编译器无输出以知道* /
:r(x),r(y)
:%ax,memory);


//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");       
}

Here I am trying to swap the char from x and store in y, and the same for y to x. I have compiled these instructions by changing movl to mov but with no success. Where is the problem in compiling/linking?

Here is the output from compiling in 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'

解决方案

unsigned char t;
asm("movl %1, %%eax;"
     "movl %%eax, %0;"
     :"=r"(t)  /* <--here */
     :"r"(*x)  /* <-- and here */
     :"%eax");

You can not move a value from a 32-bit register to a single-byte memory location. t is on the stack and x is somewhere else, but both are accessed in the same way. Problems on the other lines are similar. You should move only a byte.

Try something like this, but there are more ways to do it (I haven't tried that, read below):

unsigned char t;
asm("movb %1, %%al\n"
     "movb %%al, %0\n"
     :"=r"(t)
     :"r"(*x)
     :"%al");
asm("movb %1, %%al\n"
     "movb %%al, %0\n"
     :"=r"(*x)
     :"r"(*y)
     :"%al");
asm("movb %1, %%al\n"
     "movb %%al, %0\n"
     :"=r"(*y)
     :"r"(t)
     :"%al"); 

The whole procedure can be simplified into this:

asm("movb (%1), %%al\n"
    "movb (%2), %%ah\n"
    "movb %%ah, (%1)\n"
    "movb %%al, (%2)\n"
    : /* no outputs for compiler to know about */
    : "r" (x), "r" (y)
    : "%ax", "memory");

这篇关于gcc内联汇编错误“mov的操作数类型不匹配”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆