我正在研究一個需要與QNX-Momentics(基於eclipse,g ++ 4.6.1工具鏈)和Visual Studio 2010編譯的項目。對於一些例程,我決定去實現手動裝配,因爲即使內在函數也沒有很好的優化。第一個編譯器具有ATt & T語法,可以使用-masm = intel標誌進行「智能化」,第二種是intel方言。不是很好,但工作 - -雙重asm方言項目的問題intel/AT&T
使用Intel標誌,我可以用超越記法方面定義絕招:現在
#ifdef _WIN32
#define _cmd(...) __VA_ARGS__
__asm {
#else
#define _cmd(...) #__VA_ARGS__
asm volatile (
#endif
// constants
// set loop counter
_cmd(xor eax, eax;)
:
:
#ifdef _WIN32
}
#else
);
#endif
,一個問題是,我不能訪問本地變量或參數按名稱功能使用內聯AT & T.一個提示我在另一個線程獲得,使用像
register __m128i x asm("xmm6");
東西沒有工作,工作的局部變量,它被分配到XMM0。沒有內部函數定義的局部變量或參數,導致AT &牛逼未定義的引用,所以我決定用裸棧處理,如
_cmd(movupd xmmword ptr [eax], xmm3;)
,並遇到了新的問題:
兩個函數的參數和局部兩種方言的變量處理完全不同。請看下面的例子:
template<typename T>
void linearRegression2DAsm(unsigned int p_oNumPoints, T *p_pXcoords, T *p_pYcoords,
double *oX, double *oY, double *oXY,
double p_oAvgX, double p_oAvgY)
{
unsigned int p_rLoopsize = p_oNumPoints - (p_oNumPoints % 2);
double oAvgX[2];
,這簡單的計算上面的定義塊發出後:
_cmd(xor eax, eax;)
// p_pXccoords
_cmd(mov ecx, dword ptr [ebp+12];)
// p_pYcoords
_cmd(mov edx, dword ptr [ebp+16];)
// p_oAvgX
_cmd(movhpd xmm6, qword ptr [ebp+20];)
// p_oAvgY
_cmd(movhpd xmm7, qword ptr [ebp+28];)
_cmd(movlpd xmm6, qword ptr [ebp+20];)
_cmd(movlpd xmm7, qword ptr [ebp+20];)
_cmd(addpd xmm7, xmm6;)
// result into oAvgX
_cmd(mov eax, [ebp-32];)
_cmd(movupd xmmword ptr [ebp-32], xmm7;)
結果應該是在oAvgX,其正常工作與英特爾,但使用不會導致成功intel標記AT & T asm編譯器。其次,我擔心額外的O2-Flag可能會優化其他變量,因此不能保證在不同的編譯中構建相同的堆棧。
我需要內聯,但是看不到解決雙重方言問題的任何方法。
問候並感謝您的回覆。我知道at&t/gcc程序集中的列表和clobber列表,但是我可以如何訪問代碼塊中間的變量?使用列表中的內容,將其分配給某些內存,然後再訪問它?而且,最重要的是,如何將變量分配給sse寄存器?我到目前爲止失敗了...... – gilgamash
這是一個巨大的祕密;但變量只是一種幻覺 - 它們不存在。存在的是地址和這些地址的內存內容;並註冊。您可能想要告訴GCC,組件的輸入是某個地址(例如「變量」),以便內聯程序集可以將該地址處的數據加載到SSE寄存器中。你可能想告訴GCC SSE寄存器也是一個輸入(雖然我不確定GCC是否以這種方式正確支持SSE)。 – Brendan