2021年1月23日 星期六

C語言_main函數_trace code

緣起:
最近在研究Win32平台的組合語言, 想看一下C語言的底層長甚麼樣子,就拿最簡單的程式來看:
  int main( )
 {
 }
將心得寫成此篇blog.本篇blog有不足之處,日後補上,轉貼或引用本篇文章, 不必交代出處!

過程:
1.開啟Visual Studio 201x -> 新增專案 -> Visual C++ -> Win32主控台應用程式 -> 勾選空專案,
2.方案總管->原始程式檔->加入->新增項目->C++檔(.cpp)->檔名為Source.cpp
3.在Source.cpp內輸入下列程式碼:
  int main()
 {
 }

4.在int main()這行前面設定中斷點,按F5開始偵錯, 切到"反組譯碼", 按F11一步一步執行如下,特別注意圖上右邊三塊粉紅色區塊跟粉紅色字的區塊,最下面的區塊表示最早看到的呼叫堆疊, 只要F11按得夠久就可看到粉紅色字的區塊顯示的ExitProcess函數(VC++2010 express可看到,VS2015則看不到,那些是從google找到別人使用VS2015看到的造成runtime error當時的callStack),等該函數執行完就結束整個行程(process)[註1][註2]:

5.上圖中執行到ret(pop下一行指令的位址存到eip)後回到上一層函數內,上圖跟下圖是分兩次trace,所以stack內存的位址會不同:

6.將stack看到的參數2位址006da008打入"記憶體"內的位址這欄內按enter,解析如下:

7.將stack看到的參數3位址00687cc0打入"記憶體"內的位址這欄內按enter,解析如下:

註1:第四個步驟的附圖中提到cc cc cc cc共192Bytes的區塊是當作stack預留的guard band是錯誤的,
       因為隨後自行trace函數main內有程式碼的案例, 發現這區塊被拿來存main()內宣告的變數/指
       標,請見下圖:

註2.除了記憶體視窗/暫存器視窗/反組譯碼視窗以外,VS201x系列還提供命令視窗可輸入指令也可
       看到記憶體內容/暫存器/反組譯碼,這種方式的優點:可看出程式執行前後差異,缺點:常打指令,
       詳細指令請參考微軟網站:
https://docs.microsoft.com/zh-tw/visualstudio/ide/reference/list-memory-command?view=vs-2019


沒有留言:

張貼留言