繁体   English   中英

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

[英]Include external .asm file into C++ code

可以包含如下源代码:

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

#include "src.cpp"

.asm (assembly) 文件可以这样做吗?

你可以在 GNU C 中做的事情是asm(".include \\"src.s\\");在全局范围内让汇编程序使用GAS .include汇编程序指令进行包含

这不会预处理 asm 源,因此您最好单独组装它,并且(我认为)它不会使用通常的-I / -i包含路径。


除此之外,使用 C 预处理器:

TL:DR对于大多数编译器来说不可以,除非您将 asm 源文件转换为可以在全局范围内进入asm语句的内容。 那当然可以,但何必呢? 单独构建 asm 通常要好得多。


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

但是要在#include .S文件(GAS 语法 asm 源代码)时使其工作,您需要在 C++ 源代码中的双引号内获取.S的预处理内容。 这是不可能的: C/C++,你能#include 一个文件到字符串文字中吗?


如果你能写出这样的东西

int foo () { return 0; }

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

以某种方式在那时实际上包含src.S的内容,它会起作用。 如果你真的使用它, 编译器的 asm 输出将是

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

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

#是在GNU注释字符as语法x86的,所以#include "src.S"输入到汇编器简单地视为注释!

gcc foo.S运行在C预处理器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);
}

我测试了这个,它有效:

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 的调用约定 PDF以及他的 asm 优化指南。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM