重新加载"asm"时无法在类"CREG"中找到寄存器-Memcpy嵌入式ASM [英] can't find a register in class 'CREG' while reloading 'asm' - memcpy inline asm

查看:213
本文介绍了重新加载"asm"时无法在类"CREG"中找到寄存器-Memcpy嵌入式ASM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编译较早版本的Linux,您可以从git://github.com/azru0512/linux-0.12.git下载源代码.编译"kernel/blk_drv/ramdisk.c"时,我在下面收到错误消息,

I am trying to make an earlier verion Linux got compiled, you can download the source code from git://github.com/azru0512/linux-0.12.git. While compiling ''kernel/blk_drv/ramdisk.c'', I got error message below,

ramdisk.c:36:10: error: can't find a register in class 'CREG' while reloading 'asm'
ramdisk.c:40:10: error: can't find a register in class 'CREG' while reloading 'asm'
ramdisk.c:36:10: error: 'asm' operand has impossible constraints
ramdisk.c:40:10: error: 'asm' operand has impossible constraints

ramdisk.c中有什么

What in ramdisk.c are,

  if (CURRENT-> cmd == WRITE) {
    (void) memcpy(addr,
            CURRENT->buffer,
            len);
  } else if (CURRENT->cmd == READ) {
    (void) memcpy(CURRENT->buffer,
            addr,
            len);
  } else
    panic("unknown ramdisk-command");

记忆体是

extern inline void * memcpy(void * dest,const void * src, int n)
{
__asm__("cld\n\t"
  "rep\n\t"
  "movsb"
  ::"c" (n),"S" (src),"D" (dest)
  :"cx","si","di");
return dest;
}

我猜这是memcpy(include/string.h)内联asm问题,因此我从中删除了问题清单,但没有运气.您能帮我找出问题所在吗?谢谢!

I guess it's memcpy (include/string.h) inline asm problem, so I remove the clobber list from it but without luck. Could you help me to find out what's going wrong? Thanks!

推荐答案

GCC的语法已更改/发展了一些.

GCC's syntax for this has changed / evolved a bit.

您现在必须将每个特殊目标寄存器指定为输出操作数:

You must now specify each of the special target registers as an output operand:

...("...instructions..."
   : "=c"(n), "=S"(src), "=D"(dest)

,然后作为 same 注册为源操作数:

and then additionally as the same registers as source operands:

   : "0"(n), "1"(src), "2"(dest)

最后,您需要消除内存"(如果这会影响条件代码,我不记得了,如果这样,您还需要"cc"):

and finally you need to clobber "memory" (I can't remember offhand if this affects condition codes, if so you would also need "cc"):

   : "memory")

接下来,由于不应移动或删除此指令,因此需要使用volatile__volatile__(我不确定为什么要删除该指令,但在我的测试用例中,我不知道为什么).

Next, because this instruction should not be moved or deleted, you need to use either volatile or __volatile__ (I'm not entirely sure why but without this the instructions were deleted, in my test-case).

最后,尝试覆盖memcpy不再是一个好主意,因为gcc知道"如何实现该功能.您可以使用-fno-builtin覆盖gcc的知识.

Last, it's no longer a good idea to attempt to override memcpy because gcc "knows" how to implement the function. You can override gcc's knowledge with -fno-builtin.

这可以编译(无论如何,对于我来说,在x86-64机器上使用的gcc有点旧):

This compiles (for me anyway, with a somewhat old gcc on an x86-64 machine):

extern inline void * memcpy(void * dest,const void * src, int n)
{
    __asm__ volatile("cld\n\t"
        "rep\n\tmovsb\n\t"
        : "=c" (n), "=S" (src), "=D" (dest)
        : "0" (n), "1" (src), "2" (dest)
        : "memory", "cc");
    return dest;
}

这篇关于重新加载"asm"时无法在类"CREG"中找到寄存器-Memcpy嵌入式ASM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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