hello world在那邊?背景說明
TRANSCRIPT
Wen Liao
Hello world在那邊?背景說明
嘉義,民雄
Disclaimer
投影片資料為作者整理資料及個人意見,沒有經過嚴謹確認,請讀者自行斟酌
目標
說明分享會中live demo時的背景知識,包含
● ABI● objdump使用方式
無法看live demo的朋友可以去看:尋找"Hello World\n",實地操作。
先從API談起
引用Wikipedia:● Application programming interface的縮寫● 一組讓開發者開發應用程式的 routine、通訊
協定、或是工具● 使用相同的API,在不同平台上面重新編譯,應
該可以編譯成功,並且正確執行。
不懂?來個範例
不就是叫printf印出Hello World,有什麼稀奇。
你在Windows, Linux, ARM Linux, MIPS Linux上編譯都可
以印出Hello World
另外printf幹了什事?
不要忘記OS提供的服務稱為system call
仔細看看男人
$ man manThe table below shows the section numbers of the manual followed by the types of pages they contain. 1 Executable programs or shell commands 2 System calls (functions provided by the kernel)...
翻譯米糕
男人根據是依據數字編號的section來存放不同種類的手冊
● Section 1:執行檔● Section 2:System call● Section 3:函式庫● ...
那麼printf是system call嘛?
看來不是,那他是啥?
問男人,他說section 1和3都有printf,1是執行檔的手冊,所以只有3可以挑
那麼printf到底怎麼讓螢幕印出Hello World?
strace, 追蹤system call和signal的工具
使用了writesystem call
有人還記得stdout fd是1 嗎?
帶入要寫到stdout的字串
寫入12個bytes
回傳已經寫了12 bytes
印出來了嘿嘿
結論:printf是Standard I/O library提供的
API,讓使用者更方便的使用,以及實作stream增進效能。
$ man stdio # 男人萬歲!
在不同的OS搞不好沒有File descriptor,寫入的system也
許也不叫write
但是只要你或是廠商能夠把Standard I/O library移植到它的OS,printf照樣印給你看。
回到ABI
● Application Binary Interface的縮寫● 規範binary,也就是你的執行程式和函式庫
○ 呼叫函數行為
■ 機械碼執行的時候哪些暫存器放參數,哪些暫存器
放回傳值...○ Data type alignment○ System call呼叫規範○ ...
● 理想的世界○ 同樣的硬體條件和同樣的ABI,不同compiler編出來的
binary甚至在不同OS都可以互通○ 現實上...嘛。看起來太多細節需要處理,所以看運氣。
這次Demo要知道的ABI規範
● 單純就是如何傳遞參數給一個函數就好● 我的電腦是Intel 64-bit,使用的ABI是
■ System V AMD64 ABI● Calling convention
○ 正整數和指標參數傳遞順序■ RDI, RSI, RDX, RCX, …■ demo的printf最多用到兩個參數,demo的都是指標
範例:不要問我plt是啥,我還沒搞清楚那是三小
為什麼不是RSI而是ESI呢?kerker
有沒有很眼熟?比對一下上一頁
ABI規範,傳遞浮點變數數量
demo會用到的objdump指令
● objdump -d objfile○ 反組譯binary檔案
● objdump -t objfile○ 列出binary檔案的symbol table
■ 不知道symbol table?問估狗囉
● objdump -h objfile○ 列出binary的section資訊
■ 不知道section,請找我以前linker script的投影片或
文章
● objdump -s -j section名稱 objfile○ 列出section的內容 資料
補充無關的資料
● function prolog○ 函數被呼叫的時候,實際上機械碼準備的事
■ 儲存相關status■ 處理和設定call stack■ 處理要用的暫存器
● function epilogue○ 離開函數的時候,實際上機械碼準備的事
■ 恢復和設定call stack■ 恢復用過的暫存器■ 恢復前面儲存的status
來看這個函數
Function prolog
Function epilogue
呼叫puts,為何用edi?ABI規定。
為何設定0x4005e4?可以用objdump看看
打完收工,參考資料如下
● man○ 最man的男人
● API● ABI● System V AMD64 ABI● System V AMD64 ABI手冊(PDF)● Wikipedia: Function prologue
特別感謝Scott Tasi 大大的補充