繁体   English   中英

在不同的编译器中的程序集上定义函数

[英]Define a function on assembly in different compilers

到目前为止,我一直使用嵌入式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  

我了解发生了什么。如果功能签名相同,不同的编译器/微体系结构是否会始终将相同的寄存器地址关联?


然后在我的函数中放入一些代码(NOT __ASM__ CODE),反汇编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

暂无
暂无

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

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