2012-12-12 60 views
0

我寫了一個C++文件,我想輸出到程序集中。但是,我希望組件如下例所示進行優化:如何從visual studio 2010中的C++代碼生成優化的程序集

.386 
.model flat, c 

; Custom Build Step, including a listing file placed in intermediate directory 
; but without Source Browser information 
; debug: 
; ml -c -Zi "-Fl$(IntDir)\$(InputName).lst" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" 
; release: 
; ml -c "-Fl$(IntDir)\$(InputName).lst" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" 
; outputs: 
; $(IntDir)\$(InputName).obj 

; Custom Build Step, including a listing file placed in intermediate directory 
; and Source Browser information also placed in intermediate directory 
; debug: 
; ml -c -Zi "-Fl$(IntDir)\$(InputName).lst" "-FR$(IntDir)\$(InputName).sbr" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" 
; release: 
; ml -c "-Fl$(IntDir)\$(InputName).lst" "-FR$(IntDir)\$(InputName).sbr" "-Fo$(IntDir)\$(InputName).obj" "$(InputPath)" 
; outputs: 
; $(IntDir)\$(InputName).obj 
; $(IntDir)\$(InputName).sbr 

.code 
_TEXT SEGMENT 
_p$ = -8 
_Array$ = 8 
_size$ = 12 
ClearUsingPointers PROC NEAR ; ClearUsingPointers, COMDAT 
; Line 15 
push ebp 
mov ebp, esp 
sub esp, 204 ; 000000ccH 
push ebx 
push esi 
push edi 
lea edi, DWORD PTR [ebp-204] 
mov ecx, 51 ; 00000033H 
mov eax, -858993460 ; ccccccccH 
rep stosd 
; Line 17 
mov eax, DWORD PTR _Array$[ebp] 
mov DWORD PTR _p$[ebp], eax 
jmp SHORT $L280 
$L281: 
mov eax, DWORD PTR _p$[ebp] 
add eax, 4 
mov DWORD PTR _p$[ebp], eax 
$L280: 
mov eax, DWORD PTR _size$[ebp] 
mov ecx, DWORD PTR _Array$[ebp] 
lea edx, DWORD PTR [ecx+eax*4] 
cmp DWORD PTR _p$[ebp], edx 
jae SHORT $L278 
; Line 18 
mov eax, DWORD PTR _p$[ebp] 
mov DWORD PTR [eax], 0 
jmp SHORT $L281 
$L278: 
; Line 19 
pop edi 
pop esi 
pop ebx 
mov esp, ebp 
pop ebp 
ret 0 
ClearUsingPointers ENDP ; ClearUsingPointers 
_TEXT ENDS 
END 

上述組件是如何生成的?我能夠生成的是充滿垃圾(我不知道如何解釋它),我怎樣才能縮短它,所以我可以手動優化它,編譯它並運行它?通過垃圾,我指的是多行如下。我可以刪除它們嗎? :

PUBLIC [email protected][email protected][email protected]@[email protected]@@2_NB ; std::tr1::integral_constant<bool,0>::value 
PUBLIC [email protected][email protected][email protected]@[email protected]@2_NB ; std::tr1::integral_constant<bool,1>::value 
PUBLIC [email protected][email protected][email protected]@[email protected]@@2IB ; std::tr1::integral_constant<unsigned int,0>::value 
PUBLIC [email protected][email protected][email protected]@@2HB  ; std::_Arithmetic_traits<bool>::_Rank 
PUBLIC [email protected][email protected]@[email protected]@2HB  ; std::_Arithmetic_traits<char>::_Rank 
PUBLIC [email protected][email protected]@[email protected]@2HB  ; std::_Arithmetic_traits<signed char>::_Rank 
PUBLIC [email protected][email protected]@[email protected]@2HB  ; std::_Arithmetic_traits<unsigned char>::_Rank 
; COMDAT [email protected][email protected]@[email protected]@[email protected]@B 
CONST SEGMENT 
[email protected][email protected]@[email protected]@[email protected]@B DD 02H  ; std::_Iosb<int>::end 
CONST ENDS 
; COMDAT [email protected][email protected]@[email protected]@2W4_See[email protected]@B 
CONST SEGMENT 
[email protected][email protected]@[email protected]@[email protected]@B DD 01H  ; std::_Iosb<int>::cur 
CONST ENDS 
; COMDAT [email protected][email protected]@[email protected]@[email protected]@B 
CONST SEGMENT 
[email protected][email protected]@[email protected]@[email protected]@B DD 00H  ; std::_Iosb<int>::beg 
CONST ENDS 
; COMDAT [email protected][email protected]@[email protected]@[email protected]@B 
CONST SEGMENT 
[email protected][email protected]@[email protected]@[email protected]@B DD 020H ; std::_Iosb<int>::binary 
CONST ENDS 
+2

您發佈的代碼段確實在頂部有2個彙編指令,但其餘的';'行只是評論。你正在尋找的裝配在哪裏? – jcopenha

+0

我已添加其餘。但是這些指令是什麼,他們做了什麼? – Ivan

+2

像'.386'這樣的彙編指令並不是完全優化的代碼。現代編譯器生成'.686P'和'.XMM'。不知道這是從哪裏來的,可能有些古老。 –

回答

1

在您的項目屬性中,C/C++設置,輸出文件,選擇裝配輸出。它的輸出將取決於您選擇的C/C++優化設置

+0

我這樣做了,但生成的程序集文件的開頭並不像上面例子中的代碼。 – Ivan

0

您將通過使用/FA開關進行編譯,從Visual C++中精確獲得所需的程序集輸出。這發出了一個包含的列表,只有的說明。您的其他選項包括:

  • /FAb得到的指示,這是一個註釋,說明它的實際大小(以字節爲單位)
  • /FAc得到的指示,通過使用該指令編碼的實際字節之前
  • /FAs得到所述指令,和評論穿插從實際的C/C++源碼提取,展示了負責生成的彙編代碼

各種combina那些塊這些也是允許的,遵循CL的命令行開關的標準語法。例如,/FAcs將生成一個相當複雜的列表,其中包含源代碼中的原始字節,彙編操作碼和註釋提取。

這也可以像Keith Nicholas提到的那樣在Visual Studio GUI中的項目選項中的「C/C++ Settings」下的「Assembly Output」設置中進行控制。大多數可用的選項都在那裏,但b不是。如果你想使用它,你需要手動指定它。 (我認爲它可能實際上是一個沒有記錄的選項,但它在我見過的每一個MSVC版本都有效。)

單獨的輸出/FA非常精簡。你得到的唯一噪音是註釋,表示源代碼中負責該特定塊彙編指令的行。這正是您的問題的第一個例子所顯示的內容。我希望有一種方法可以防止這些被包含,但我找不到。這使得很容易區分函數的兩個變體的實現。我有一個應用程序,它可以手動刪除它們。

請注意,當然,這與優化沒有任何關係。編譯器生成的實際二進制代碼(假設您未通過/c開關,該開關僅在沒有鏈接的情況下進行編譯,但仍會生成彙編列表)爲,與相同,無論/FA切換你使用。這些附加信息都沒有任何影響。這只是爲了您的利益,在您分析代碼時幫助您。

至於你的真的問題,關於消除你的第二個片段中顯示的「垃圾」&hellip;這只是因爲包含了標準庫頭文件,這些頭文件定義了一些符號以及編譯器必須嵌入到目標文件中的其他垃圾,以便鏈接器能夠完成工作。沒有辦法阻止這種情況出現。你只有兩個選擇:

  1. 如果你實際上並沒有使用標準庫,那麼不包括任何其頭。當使用/FA時,這會給你更多「更清潔」的輸出。

  2. 如果你的使用標準庫,並且需要它來獲得編譯代碼,那麼你只需要忽略它。

注意,「垃圾」是僅在文件的頂部,使得它能夠容易地手動剝離出來。當你試圖分析生成的目標代碼時,無論是爲了理解編譯器在做什麼,或者將它用作構建自己的優化實現的起點,你所需要做的就是在文本編輯器中加載文件,搜索查看您感興趣的功能的名稱,然後右鍵拖動到相關的代碼。那裏不會有垃圾;只是所需的代碼。我應該指出,如果你打算採用編譯器生成的彙編列表,稍微調整代碼,然後通過彙編程序運行整個shebang(例如,例如,MASM),那麼你可以忘掉它。不能保證它會起作用。 /FA彙編列表不能被反饋到彙編程序。它們只是信息性的。從它們中提取需要的信息,使用編譯器的版本編寫彙編代碼作爲基礎,然後將乾淨的源文件送入彙編器。

相關問題