回答
誠然這是個人的偏見,你怎麼喜歡學習編程。
但相對於在特定的彙編語言,我發現了一個辦法這對我來說已經不是閱讀彙編語言指令集參考手冊和/或書籍(如有的話)更爲有用。
我通常做找出如何組裝一個新的CPU工作/一個CPU不知道的我一個操作系統平臺,我不還製作是利用開發工具鏈。像這樣:
爲自己安裝目標CPU的(交叉)編譯器和反彙編程序。現在,GNU gcc的/ binutils無處不在通常意味着這是
gcc
和objdump -d
。創建一批的小程序/小片的源代碼,如:
extern int funcA(int arg);
extern int funcB(int arg1, int arg2);
extern int funcC(int arg1, int arg2, int arg3);
extern int funcD(int arg1, int arg2, int arg3, int arg4);
extern int funcE(int arg1, int arg2, int arg3, int arg4);
extern int funcF(int arg1, int arg2, int arg3, int arg4, int arg5);
extern int funcG(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
extern int funcH(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6,
int arg7);
int main(int argc, char **argv)
{
printf("sum of all funcs: %d\n",
funcA(1) + funcB(2, 3) + funcC(4, 5, 6) + funcD(7, 8, 9, 10) +
funcE(11, 12, 13, 14, 15) + funcF(16, 17, 18, 19, 20, 21) +
funcG(22, 23, 24, 25, 26, 27, 28) + funcH(29, 30, 31, 32, 33, 34, 35));
return 12345;
}
編譯這些與編譯器優化和拆卸生成目標代碼。
代碼的結構非常簡單,足以說明如何運行。到函數調用,傳遞參數和返回值,管理寄存器空間 wrt。在進行函數調用時寄存器被保留/不穩定。它還會顯示一些用於初始化常量數據的基本彙編代碼,以及像堆棧訪問和管理那樣的「粘合」。將此擴展爲簡單的C語言結構,如循環和
if
/else
或switch
語句。始終保持對外部未定義功能幾個電話,因爲這樣做會防止編譯器優化,從扔你所有的「測試代碼」出來的,而當你使用if()
測試switch()
,對argc
(或其他功能參數)謂詞,因爲編譯器無法預測即(並且因此優化代碼的「構建塊」)。延伸此使用含有不同的基本數據類型的序列
struct {}
和class {}
定義,以便找出編譯器在存儲器中,其中彙編指令用於訪問字節/字/整型/多頭/浮標如何安排這些等
所有這些作品的測試代碼,你可以故意改變(例如,使用不同的操作比+
),和/或進行更復雜,以瞭解更多有關指令集和ABI的某些片段。
你做了之後,看着在輸出中,找到平臺ABI的副本(電子或沒有)。其中包含規則手冊,說明如何完成上述工作/爲什麼完成上述工作,它將幫助您瞭解這些規則適用於特定平臺的原因。瞭解上述內容非常重要,因爲在編寫自己的彙編代碼時,必須將其與其他非彙編代碼(除非用於純演示)進行交互。這就是你需要遵守規則的地方,所以即使你不瞭解他們,至少知道規則手冊在哪裏。
只有在那之後,我才建議你實際追蹤特定平臺的指令集參考。
這是因爲,當你通過上述第一消失了,那麼你已經有足夠的經驗/你已經看到已經足以啓動一個小的C程序,編譯它到彙編源,修改了一下,組裝並鏈接它,看看你的修改是否做它應該做的。
試圖在這個階段使用一些更少見的/專門的指令會容易得多,因爲你已經看到了函數調用是如何工作的,需要什麼樣的粘合代碼來將你的程序集與界面的其他部分程序,你已經使用了工具鏈,所以你不需要從頭開始完全。
即,要總結這一切,我的建議是從學習彙編自上而下,而不是從下往上。
旁註:
爲什麼我建議使用編譯器優化這種簡單的例子分析編譯器生成的彙編代碼是什麼時候?
那麼,答案是因爲,違反直覺的一些,生成的彙編代碼是簡單得多如果你讓編譯器優化地獄的東西。沒有優化,編譯器通常會創建「愚蠢的」代碼,例如將所有變量放入堆棧,從那裏保存並恢復它們,無論您看到什麼原因,註冊保存/恢復/初始化只是爲了覆蓋下一條指令以及更多這樣的內容。因此,發射的代碼量要大得多。它夾雜着粗糙,而且很難理解。編譯器優化可以將這個問題修剪到最基本的部分,這就是你想要了解平臺ABI以及可以理解的東西。因此,使用編譯器優化。
這是一個非常好的idead/answer。非常感謝。 – gideon 2014-02-18 07:03:44
這是我見過的最好的答案之一。 – 2016-05-07 07:55:13
- 1. 芯片組信息 - AMD或英特爾
- 2. 英特爾TBB和Cilk Plus線程親和力英特爾MIC
- 3. 英特爾ESG教程和示例需要
- 4. 英特爾SSE和AVX示例和教程
- 5. 什麼是英特爾®安裝和配置軟件(英特爾®SCS)
- 6. 我如何安裝英特爾編譯器和英特爾mpi的提升?
- 7. 英特爾HAXM安裝失敗
- 8. 我不能安裝英特爾haxm
- 9. 在組裝中設置文本和背景英特爾
- 10. 英特爾AVX2組件開發
- 11. 創建使用英特爾組件
- 12. 與英特爾伽利略gen2的英特爾xdk守護進程
- 13. 英特爾xdk應用程序安裝替換以前的apk
- 14. 分割的64位英特爾(和非英特爾)處理器
- 15. FFT使用英特爾MKL和英特爾IPP
- 16. 英特爾TBB使用的線程數
- 17. 英特爾XDK(在HTML5應用程序)
- 18. 棄用警告(哈特爾教程)
- 19. 正則表達式教程或書
- 20. Webots的資源(教程或書籍)
- 21. jQuery與Rails 3.1.3電子書或教程?
- 22. 學說2教程或書籍?
- 23. 我使用英特爾Cilk的加數組符號英特爾Cilk的加數組符號
- 24. 如何開始使用圖書館英特爾ipp?
- 25. Angular2英雄教程 - 英雄課
- 26. 針對OpenCL應用程序安裝安裝英特爾SDK,並獲得以下
- 27. 英特爾8086處理器
- 28. 英特爾XDK分層表
- 29. 英特爾Fortran損壞DLL
- 30. 英特爾XDK - 通過pushMobi
我不瞭解有關nasm教程,但可以獲取[Intel Software Developer Manuals](http://www.intel.com/content/www/us/en/processors/architectures-software-developer- manuals.html),你應該發現很有幫助。 – 2013-03-08 15:48:14
intel.com上的教程?這聽起來像個可笑的玩笑。從[Paul Carter的教程](http://www.drpaulcarter.com/pcasm/)開始。令人驚訝的是,它基於NASM。當您掌握32位程序集時,請切換到64. – 2013-03-08 16:27:52
我推薦Ray Seyfarth介紹適用於Linux的64位英特爾彙編語言編程。本書使用YASM而不是NASM,但YASM接受AFAIK幾乎所有的NASM代碼,並且還支持DWARF2調試數據格式等。本書也有一些SSE和AVX代碼,並且它只假定一些編程背景並解釋二進制和十六進制數字等。我已經在DOS時間學習了x86程序集,但是本書可以作爲Linux x86-64程序集中有用的參考。 – nrz 2013-03-08 21:39:05