【问题标题】:compiling linux 0.0.1 => error: ‘asm’ operand has impossible constraints __asm__("cld\n"编译 linux 0.0.1 => 错误:'asm' 操作数具有不可能的约束 __asm__("cld\n"
【发布时间】:2017-05-11 02:09:34
【问题描述】:

我正在尝试从我的 64 位英特尔机器上的源代码编译 linux 内核 0.0.1。 只是为了填写 boot 和 main 我不得不修改所有 makefile 以获得 32 位编译。

所以,这是 make 的输出:

In file included from traps.c:7:0:
../include/string.h:128:22: warning: conflicting types for built-in function ‘strchr’
 extern inline char * strchr(const char * s,char c)
                      ^
../include/string.h:145:22: warning: conflicting types for built-in function ‘strrchr’
 extern inline char * strrchr(const char * s,char c)
                      ^
../include/string.h:379:22: warning: conflicting types for built-in function ‘memchr’
 extern inline void * memchr(const void * cs,char c,int count)
                      ^
../include/string.h:395:22: warning: conflicting types for built-in function ‘memset’
 extern inline void * memset(void * s,char c,int count)
                      ^
In file included from traps.c:11:0:
../include/linux/kernel.h:5:1: warning: function return types not compatible due to ‘volatile’
 volatile void panic(const char * str);
 ^
../include/linux/kernel.h:5:1: warning: function return types not compatible due to ‘volatile’
../include/linux/kernel.h:5:1: warning: function return types not compatible due to ‘volatile’
In file included from traps.c:7:0:
../include/string.h: In function ‘strcpy’:
../include/string.h:29:1: error: ‘asm’ operand has impossible constraints
 __asm__("cld\n"
 ^
Makefile:24: set di istruzioni per l'obiettivo "traps.o" non riuscito

string.h的部分代码如下:

extern inline char * strcpy(char * dest,const char *src)
{
__asm__("cld\n"
    "1:\tlodsb\n\t"
    "stosb\n\t"
    "testb %%al,%%al\n\t"
    "jne 1b"
    ::"S" (src),"D" (dest):"si","di","ax");
return dest;
}

我不知道为什么原始代码无法编译。 到现在我成功编译了:boot和init subdir。

非常感谢

【问题讨论】:

    标签: c linux compilation


    【解决方案1】:

    我认为问题在于 register clobber list 与输入重叠。

    "S"代表寄存器esi,而"D"代表寄存器edi;但随后clobber列表包含"si""di",它们是这些寄存器的低16位。也许旧 GCC 版本忽略了这一点,但新版本不允许重叠。

    来自docs here

    Clobber 描述不能以任何方式与输入或输出操作数重叠。

    解决方案,只需将它们从列表中删除:

    ...
    ::"S" (src),"D" (dest) :"ax", "cc");
    

    顺便说一句,我还将 clobber 添加到 "cc",因为该程序集修改了 e 标志。

    【讨论】:

    • 谢谢,它适用于这个例子,但现在错误在下一个函数中向前移动,这里又使用了一个寄存器。 extern inline char * strncpy(char * dest,const char *src,int count) { __asm__("cld\n" "1:\tdecl %2\n\t" "js 2f\n\t" "lodsb\n \t" "stosb\n\t" "testb %%al,%%al\n\t" "jne 1b\n\t" "rep\n\t" "stosb\n" "2:" :: "S" (src),"D" (dest),"c" (计数):"si","di","ax","cx");返回目的地; }
    • @JoAccount:同样的事情。 clobber 列表应该只是:"ax", "cc"。 “cx”与代表寄存器ecx"c"重叠。
    猜你喜欢
    • 2016-11-24
    • 1970-01-01
    • 2019-10-26
    • 2018-02-11
    • 1970-01-01
    • 2012-07-22
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多