将外部.asm文件包含在C ++代码中

时间:2017-10-20 13:34:26

标签: c++ assembly include

可以包含以下源代码:

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

#include "src.cpp"

是否可以为.asm(程序集)文件执行此操作?

1 个答案:

答案 0 :(得分:1)

TL:DR 没有大多数编译器,除非你将asm源文件转换成可以进入全局范围内的asm语句的内容。然后肯定,但为什么要打扰;分别建立asm通常要好得多。

GNU C inline-asm语法允许您将任意程序集放在全局范围内,以便与编译器生成的asm一起组装。在任何C / C ++函数之外使用asm("instructions and assembler directives ...");

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

如果你能写出像这样的东西

int foo () { return 0; }

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

实际包含src.S内容的方式,它会起作用。如果你真的使用它,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.Sfoo.S上运行C预处理器(生成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);
}

我对此进行了测试,并且有效:

peter@volta:~/src/SO$ gcc -Wall -O2 include-asm.c
peter@volta:~/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)的情况。 (如果您使用的是x86 asm,请参阅Agner Fog's calling conventions PDF以及他的asm优化指南。)