大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家講的是嵌入式開發里的反匯編文件(.s, .lst, .dump)。
痞子衡在第四、五、六節課分別介紹了編譯器/鏈接器生成的3種output文件(relocatable、map、exectuable文件),這3種文件都是側重的代碼經過匯編/鏈鏈接后的二進制數據在存儲中分布情況。如果想知道二進制數據對應的機器碼具體是什么意思應該怎么辦?痞子衡今天要介紹的反匯編文件會給你答案。
一、標准匯編源文件
使用IAR進行編譯的時候會在D:\myProject\bsp\builds\demo\Release\List目錄下生成.s文件,每一個relocatable文件都對應着一個.s文件,這是編譯器對C源文件進行匯編后得到的匯編文件。以task.c匯編生成的task.s為例:
task.s文件就是用匯編語言對task.c文件的逐句匯編式翻譯,下面僅列出normal_task()函數的匯編代碼,如果你願意的話,你可以直接用這個task.s文件替代task.c文件放進工程里,功能是一樣的。
SECTION `.text`:CODE:NOROOT(1)
CFI Block cfiBlock0 Using cfiCommon0
CFI Function normal_task
CFI NoCalls
THUMB
// 17 void normal_task(void)
// 18 {
// 19 s_variable0 *= 2;
normal_task:
LDR R0,??DataTable1
LDR R0,[R0, #+0]
MOVS R1,#+2
MULS R0,R1,R0
LDR R1,??DataTable1
STR R0,[R1, #+0]
// 20 }
BX LR ;; return
CFI EndBlock cfiBlock0
// 21
task.s文件最后還會給出文件里的object在各section中的總size情況。
// 20 bytes in section .bss
// 4 bytes in section .data
// 4 bytes in section .noinit
// 86 bytes in section .text
// 16 bytes in section .textrw
//
// 102 bytes of CODE memory
// 28 bytes of DATA memory
二、中間匯編list文件
使用IAR進行編譯的時候會在D:\myProject\bsp\builds\demo\Release\List目錄下生成.lst文件,每一個relocatable文件都對應着一個.lst文件,這是編譯器對C源文件進行匯編后得到的匯編文件的補充信息文件。繼續以task.c匯編生成的task.lst為例:
task.lst文件在task.s的基礎上還加入了對匯編指令的機器碼翻譯信息,其中有0x....表明該文件沒有經過全局的鏈接,所以還無法確定機器碼。
\ In section .text, align 2, keep-with-next
17 void normal_task(void)
18 {
19 s_variable0 *= 2;
\ normal_task: (+1)
\ 00000000 0x.... LDR R0,??DataTable1
\ 00000002 0x6800 LDR R0,[R0, #+0]
\ 00000004 0x2102 MOVS R1,#+2
\ 00000006 0x4348 MULS R0,R1,R0
\ 00000008 0x.... LDR R1,??DataTable1
\ 0000000A 0x6008 STR R0,[R1, #+0]
20 }
\ 0000000C 0x4770 BX LR ;; return
21
task.lst文件最后還給出最大棧使用的分析以及各object具體size情況。
Maximum stack usage in bytes:
.cstack Function
------- --------
24 heap_task
24 -> __aeabi_memcpy
24 -> __aeabi_memset
24 -> free
24 -> malloc
0 normal_task
0 ram_task
Section sizes:
Bytes Function/Label
----- --------------
4 ??DataTable1
4 ??DataTable1_1
4 ??DataTable1_2
60 heap_task
4 n_variable1
14 normal_task
16 ram_task
16 s_array
4 s_variable0
4 s_variable2
三、完整匯編dump文件
dump文件是所有list文件的集合,也是整個image文件的機器碼數據的逐句匯編式翻譯,還是以task.c里的normal_task()為例,在list文件中我們會看到部分未知機器碼0x....,而在dump文件里這部分位置機器碼被填充成真實的機器碼。有了dump文件,我們就可以從匯編角度對整個工程進行解讀分析。
// s_variable0 *= 2;
$t:
`.text12`:
normal_task:
0xcc: 0x4812 LDR.N R0, `.text_8` ; `.data$$Limit`
0xce: 0x6800 LDR R0, [R0]
0xd0: 0x2102 MOVS R1, #2
0xd2: 0x4348 MULS R0, R1, R0
0xd4: 0x4910 LDR.N R1, `.text_8` ; `.data$$Limit`
0xd6: 0x6008 STR R0, [R1]
// }
0xd8: 0x4770 BX LR
四、使用ielfdumparm.exe生成dump文件
dump文件默認是不生成的,但是IAR里提供了工具可以幫我們生成dump文件,這個工具叫ielfdumparm.exe。
位置:\IAR Systems\Embedded Workbench xxx\arm\bin\ielfdumparm.exe
用法:ielfdumparm.exe --source --code demo.elf -o demo.dump
至此,嵌入式開發里的反匯編文件(.s, .lst, .dump)文件痞子衡便介紹完畢了,掌聲在哪里~~~
歡迎訂閱
文章會同時發布到我的 博客園主頁、CSDN主頁、微信公眾號 平台上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。