编译linux内核2.4.0时内联汇编错误

Posted

技术标签:

【中文标题】编译linux内核2.4.0时内联汇编错误【英文标题】:inline assembly error while compiling linux kernel 2.4.0 【发布时间】:2016-01-09 20:58:06 【问题描述】:

我正在尝试在 Ubuntu 15.10 32 位上编译 linux 内核 2.4.0。我在构建时收到此错误:

linux/include/asm/checksum.h:161:2:错误:缺少终止“字符 linux/include/asm/checksum.h:173:3:错误:缺少终止“字符 ...

gcc 抱怨的是内联汇编中的引号:

static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
                                                     struct in6_addr *daddr,
                                                     __u32 len,
                                                     unsigned short proto,
                                                     unsigned int sum)

        __asm__("
                addl 0(%1), %0 //line 162
                adcl 4(%1), %0
                adcl 8(%1), %0
                adcl 12(%1), %0
                adcl 0(%2), %0
                adcl 4(%2), %0
                adcl 8(%2), %0
                adcl 12(%2), %0
                adcl %3, %0
                adcl %4, %0
                adcl $0, %0
                "                    // line 173
                : "=&r" (sum)
                : "r" (saddr), "r" (daddr),
                  "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));

        return csum_fold(sum);

我不知道为什么会这样。是因为 gcc 版本不兼容吗?我当前的 gcc 版本是 gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010。

【问题讨论】:

您能否指出第 161 行和第 173 行是哪一行?为什么你的头文件中有代码实现? 难道你不应该在每条指令的前后加上引号吗? IE。 "addl 0(%1), %0\n\t" @WeatherVane 刚刚添加了行号注释。这是 linux 内核源代码 2.4.0 不是我写的。由于它是内联函数,我认为在头文件中是正常的。 @Michael 我也很困惑。所以我不确定它是否是一些较旧的 gcc 语法。这是生产 linux 内核代码,所以我不认为这是某种错误。 @MarcGlisse 是的,只是想学习内核代码,而不是真正使用图像。因为它是更小的代码库。 【参考方案1】:

最近的 gcc 不支持多行字符串文字。较新的(2.4.0 是古老的!)版本的内核有:

    asm("addl 0(%1), %0     ;\n"
        "adcl 4(%1), %0     ;\n"

等等。它曾经受支持,例如在version 3.2 中,但在3.3 中删除了支持:

预处理器不再接受多行字符串文字。它们在 3.0、3.1 和 3.2 中已弃用。

【讨论】:

以上是关于编译linux内核2.4.0时内联汇编错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 gcc 编译内联汇编时出错,“shl”

x86 内联汇编器标志

扩展内联汇编 gcc - 计算二次公式根

GCC 内联汇编中的标签

GCC 内联汇编错误:表达式后出现垃圾 `(%ebp)+4'

GCC 内联汇编错误:变量 '%al' 的 asm 说明符与 asm clobber 列表冲突