到現在爲止,我用內聯asm
來破解它不是獲得良好性能的最佳選擇。我從彙編開始,但是我正在編寫我的機器(GCC),但結果代碼是在64位(Sandy Bridge & Haswell)中的其他(ICC)上運行的。在不同的編譯器中定義一個彙編函數
要調用一個沒有參數的函數,我們可以用CALL
來做,但我不太明白如何用參數調用一個函數,並且因爲我試圖在所有函數中使用內聯__asm__
。這是一個不錯的選擇?
我的功能:
void add_N(size_t *cnum, size_t *ap, size_t *bp, long &n, unsigned int &c){
__asm__(
//Insert my code here
);
}
當我看到拆卸(海灣合作委員會),我有:
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__
CODE),以及desassembly PUSH
很多寄存器裏面。爲什麼發生?爲什麼我不需要推%rax
和%rsi
(例如),並且需要推r13
,r14
和r15
? 如果我需要推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)
'jmp'是一個無條件的*跳轉*,而不是*調用*。如果你對一個函數執行'jmp',然後使用'ret'指令返回,堆棧將不會正確設置返回,你將會有一些非常奇怪的行爲,因爲'ret'指令會跳到一些未知的位置。 –
謝謝你,我說因爲我在其他地方讀過它.. –