GNU可以作为汇编文件(.s)中的流程结构和函数原型吗?

时间:2016-09-27 09:25:09

标签: gcc assembly

正如我们所知,汇编文件(.S)会在汇编之前进行预处理,但我发现在预处理之后,结果汇编文件中可能会有结构/函数原型,gnu如何处理这些原型?只是忽略了它?

例如,以下命令:

  

gcc -E -o tmp.result arch / x86 / boot / copy.S -Iinclude / -Iarch / x86 / include /

,生成的程序集文件(tmp.result)为:

# 1 "arch/x86/boot/copy.S"                                                                                                                                                                   
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "arch/x86/boot/copy.S"
# 11 "arch/x86/boot/copy.S"
# 1 "include/linux/linkage.h" 1
# 1 "include/linux/compiler.h" 1
# 5 "include/linux/linkage.h" 2
# 1 "include/linux/stringify.h" 1
# 6 "include/linux/linkage.h" 2
# 1 "include/linux/export.h" 1
# 26 "include/linux/export.h"
struct kernel_symbol
{
 unsigned long value;
 const char *name;
};
# 7 "include/linux/linkage.h" 2
# 1 "arch/x86/include/asm/linkage.h" 1
# 8 "include/linux/linkage.h" 2
# 12 "arch/x86/boot/copy.S" 2
.code16
.text
GLOBAL(memcpy)
 pushw %si 
 pushw %di 
 movw %ax, %di 
 movw %dx, %si 
 pushw %cx 
 shrw $2, %cx 
 rep; movsl
 popw %cx 
 andw $3, %cx 
 rep; movsb
 popw %di 
 popw %si 
 retl
ENDPROC(memcpy)

但是在尝试组装此文件时:

  

as -o tmp.o tmp.result

产生以下错误:

include/linux/export.h: Assembler messages:
include/linux/export.h:26: Error: no such instruction: `struct kernel_symbol'
include/linux/export.h:27: Error: junk at end of line, first unrecognized character is `{'
include/linux/export.h:28: Error: no such instruction: `unsigned long value'
include/linux/export.h:29: Error: no such instruction: `const char *name'
include/linux/export.h:30: Error: junk at end of line, first unrecognized character is `}'
arch/x86/boot/copy.S:20: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:34: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:36: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:49: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:51: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:58: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:60: Error: invalid character '(' in mnemonic
arch/x86/boot/copy.S:67: Error: invalid character '(' in mnemonic

似乎汇编程序无法处理tmp.result中的结构。 Linux源代码(.S)如何通过组装?

1 个答案:

答案 0 :(得分:4)

as无法处理struct和函数原型 - 它们只适用于C编译器,并且可以进入&#34;拉入&#34;在你的预处理错误。事实上,如果您查看提供struct定义的标题,you'll see

#ifndef __ASSEMBLY__
struct kernel_symbol
{
        unsigned long value;
        const char *name;
};

因此,上方的标题被认为包含在汇编和C中,但您没有定义__ASSEMBLY__来告诉它您将其包含在汇编文件。

有趣的是,gcc确实有一个内置的__ASSEMBLER__预定义宏来区分汇编文件或C文件中的包含,但似乎内核does not use it for historical reasons依赖于手动定义{{ 1}}预处理汇编文件时。

长话短说:要从预处理器获得正确的输出,你应该做类似的事情

__ASSEMBLY__

(免责声明:我并不完全熟悉内核构建过程,上面的行可能有包含路径的其他问题,或者正确的方法是调用gcc -E -D__ASSEMBLY__ -o tmp.result arch/x86/boot/copy.S -Iinclude/ -Iarch/x86/include/ 而不是{{1或者其他 - 我不知道)