c++ - 在不同的编译器中定义汇编函数

标签 c++ performance inline-assembly

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

要调用不带参数的函数,我们可以使用 CALL,但我不太了解如何调用带参数的函数,因此我尝试使用内联 __asm__ 在所有函数中。这是一个不错的选择吗?

我的功能:

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

    __asm__(
        //Insert my code here
    );

}

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

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  

我明白发生了什么。如果函数签名相同,不同的编译器/微架构是否总是关联相同的寄存器地址?


然后在我的函数中放入一些代码(不是 __ASM__ 代码),然后反汇编 PUSH 很多寄存器。为什么会这样?为什么我不需要推送%rax%rsi(例如),而需要推送r13r14r15? 如果我需要压入 r** 寄存器,我可以在 inline __asm__ 中做吗?

0x100001ea0 <+0>:   pushq  %rbp
0x100001ea1 <+1>:   movq   %rsp, %rbp
0x100001ea4 <+4>:   pushq  %r15
0x100001ea6 <+6>:   pushq  %r14
0x100001ea8 <+8>:   pushq  %r13
0x100001eaa <+10>:  pushq  %r12
0x100001eac <+12>:  pushq  %rbx
0x100001ead <+13>:  movq   %rdi, -0x30(%rbp)
0x100001eb1 <+17>:  movq   %rsi, -0x38(%rbp)
0x100001eb5 <+21>:  movq   %rdx, -0x40(%rbp)
0x100001eb9 <+25>:  movq   %rcx, -0x48(%rbp)
0x100001ebd <+29>:  movq   %r8, -0x50(%rbp)

最佳答案

对于最后一个问题 - 是的,只要它们使用相同的 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

关于c++ - 在不同的编译器中定义汇编函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35314503/

相关文章:

用于读取结构的基于 C++ 范围的循环

java - BigInteger 方法 mod() 性能很差。对于大量的数据是否有更好的权衡?

linux - 有什么方法可以在Linux平台上编译Microsoft样式的内联汇编代码?

c - (GNU内联汇编)如何使用未从C变量分配或复制到C变量的寄存器?

c++ - 当仅需要 X-Y 旋转时,3D 对象沿所有三个轴旋转

c++ - 包裹在 rice/ruby 中的纯虚拟 c++ 类在运行时引发 TypeError ("is not a class (Module)")

c++ - cpp异常获取抛出调用者的详细信息

python - 使用 urllib.request 获取股票数据

arrays - 为什么在 Java 和 C 等语言中数组索引从 0 开始而不是从 1 开始?

c++ - 汇编/__asm 内联