2017-10-20 88 views
1

它可以包括源代码,如下所示:包括外部.ASM文件到C++代码

extern "C" 
{ 
    #include "src.c" 
} 

#include "src.cpp" 

是否有可能做这样对于.ASM(组件)文件?

+0

您可以将ASM文件添加到命令行usuall(GCC例如),它会用正确地处理(也大部分)并被添加到二进制文件中。将它包含到C(++)中,除非是内联汇编,否则它不会/不能。 –

+0

不同的编译器对内联汇编的支持不同。据我所知,他们都没有使用标准的C++ ['asm' keyword](http://en.cppreference.com/w/cpp/language/asm),但也许有些人会这样做。对于PC来说,有两种主要的汇编语言语法,Intel和AT&T,你也必须要这样做。最好的做法是用汇编程序汇编汇编代码,单独翻译。 –

+1

直接回答你的问题将不是 – Asesh

回答

2

TL:DR 没有大多数编译器,除非您将asm源文件嵌入到全局范围内的asm语句中。那么确定,但为什么要麻烦;单独建造集成通常要好得多。


GNU C直列汇编语法允许你把任意组装,在全球范围内将与编译器生成的ASM一起组装。在任何C/C++函数之外使用asm("instructions and assembler directives ...");

但是为了在包含.S文件(GAS语法asm源代码)的情况下工作,您需要在C++源代码中使用双引号内的.S的预处理内容。这是不可能的:C/C++, can you #include a file into a string literal?


如果你能在某种程度上会实际上包括src.S在这一点上的内容写入这样的事情

int foo() { return 0; } 

asm ("#include \"src.S\" "); // doesn't work 

,它会工作。如果你从字面上使用的compiler's asm output will be

 .file "example.cpp" 
     .text 
.Ltext0: 
#APP 
     #include "src.S" 
#NO_APP 

# omitted some .directives 
foo: 
    xorl %eax, %eax 
    ret 

# is the comment character in GNU as syntax for x86,所以#include "src.S"输入到汇编器简单地视为注释!

gcc foo.S它馈送到汇编器之前运行在foo.S(以产生foo.s)的下预处理器。但是这不会发生在编译器生成的asm输出上;在编译之前,只有C/C++源通过CPP提供。


您可以编写一个双引号括起来每一行,酷似你的asm语句的身体里面写的是什么的ASM源文件。

例如,bar.inline-asm可能是

".p2align 4      \n\t" 
".globl bar      \n\t" 
".type bar, @function   \n\t" 
"bar:       \n\t" 
"  lea (%rdi,%rsi,2), %eax \n\t" 
"  ret      \n\t" 
".size bar, .-bar    \n\t" 

(注意,这是GNU C Basic ASM,所以我们并不需要将%字符的两倍。)

有了这个src.c,我们可以测试它:

// extern "C" // if this is in C++. 
int bar(int a, int b); 

asm(
#include "bar.inline-asm" 
); 


int main(void) { 
    return bar(2, 4); 
} 

我进行了测试,它的工作原理:

[email protected]:~/src/SO$ gcc -Wall -O2 include-asm.c 
[email protected]:~/src/SO$ ./a.out; echo $? 
10 
# correct result for 2 + 4*2 

$ disas a.out  # alias for objdump -drwC -Mintel 

... 
0000000000000530 <main>: 
530: be 04 00 00 00   mov esi,0x4 
535: bf 02 00 00 00   mov edi,0x2 
53a: e9 11 01 00 00   jmp 650 <bar>  # optimized tail-call to bar() 
53f: 90      nop 

... 
0000000000000650 <bar>: 
650: 8d 04 77    lea eax,[rdi+rsi*2] 
653: c3      ret  
654: 66 2e 0f 1f 84 00 00 00 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 
65e: 66 90     xchg ax,ax 

显然在这种情况下,这样做没有什么优势,而只需要gcc -O2 foo.c asm.S来构建单独的目标文件,这些目标文件在最后链接在一起。

它不会使名称更容易处理,即它不会简化_bar(Windows)与bar(Linux)的情况。 (见Agner Fog's calling conventions PDF,以及他的ASM优化指南,如果你正在使用的x86汇编的任何东西。)

+0

我有一个预感OP在Windows上唱MSVC –

+0

@MichaelPetch:这也是我的猜测,但他们没有说,并且对于GNU C inline asm语法有一个半有趣的答案。 '__asm {#include“是什么”}“在MSVC的全局范围内工作?或者你也许可以在一个你永远不会打电话的虚拟功能中做到这一点? –

+1

在32位MSVC/C++'__asm {}'语句(内联程序集)不能出现在全局范围内。在64位代码中,__asm {}'不再受支持。 –