在不同的编译器

时间:2016-02-10 11:53:23

标签: c++ performance inline-assembly

到目前为止,我使用内联asm来破坏它不是获得良好性能的最佳选择。我从汇编开始,但我在我的机器(GCC)中进行编程,但结果代码是在64位(Sandy Bridge& Haswell)中以其他方式(ICC)运行。

要调用没有参数的函数,我们可以使用CALL来完成,但我不太了解如何使用参数调用函数,因此我尝试使用内联{{1}在所有功能里面。这是一个不错的选择?

我的功能:

__asm__

当我看到反汇编(使用GCC)时,我有:

void add_N(size_t *cnum, size_t *ap, size_t *bp, long &n, unsigned int &c){

    __asm__(
        //Insert my code here
    );

}

我理解发生了什么..如果函数签名相同,不同的编译器/微体系结构是否总是关联相同的寄存器地址?

然后在我的函数(NOT add_N(unsigned long*, unsigned long*, unsigned long*, long&, unsigned int&): 0x100001ff0 <+0>: pushq %rbp 0x100001ff1 <+1>: movq %rsp, %rbp 0x100001ff4 <+4>: movq %rdi, -0x8(%rbp) 0x100001ff8 <+8>: movq %rsi, -0x10(%rbp) 0x100001ffc <+12>: movq %rdx, -0x18(%rbp) 0x100002000 <+16>: movq %rcx, -0x20(%rbp) 0x100002004 <+20>: movq %r8, -0x28(%rbp) 0x100002008 <+24>: popq %rbp 0x100002009 <+25>: retq CODE)中放入一些代码,并在desassembly __ASM__中放入很多寄存器。为什么会这样?为什么我不需要推PUSH%rax(例如),需要推%rsir13r14? 如果我需要推送r15寄存器,我可以在r**吗?

inline __asm__

1 个答案:

答案 0 :(得分:1)

对于最后一个问题 - 是的,它将使用相同的寄存器参数,只要它们使用相同的ABI。这里定义了Linux x86_64 ABI:http://www.x86-64.org/documentation/abi.pdf并且所有编译器都必须符合它。具体来说,您对第16页 - 参数传递感兴趣。

我认为Windows的ABI略有不同。因此,您无法运行在Linux上编译并在Windows上运行的程序或库(例如,还有一些其他原因)。

有关gcc内联汇编的详细信息,请查看一些现有教程,因为它是一个很长的主题。这是一个好的开始:http://asm.sourceforge.net/articles/rmiyagi-inline-asm.txt