5.1.2 不同架構下匯編指令分析
1.鯤鵬架構
針對5.1.1節在鯤鵬架構下編譯的程序kunpeng_demo,通過反匯編工具查看它的匯編指令,詳細步驟如下:
步驟1:安裝反匯編工具objdump。objdump在工具包binutils中,可以通過yum安裝該工具包,命令如下:
yum install -y binutils
步驟2:反編譯kunpeng_demo,命令及回顯如下(因為反編譯后的匯編代碼太多,這里只保留與main方法相關的匯編代碼):

這樣,就得到了C語言代碼對應的匯編代碼。
下面對main函數的代碼逐行分析,同時對鯤鵬架構指令和寄存器進行簡單介紹。
1)sub sp,sp,#0x10
sp寄存器保持棧頂位置,這里向下擴展了16字節,這16字節可以用來給后面的變量分配內存空間,棧默認最小擴展空間是16字節,每次擴展空間是16字節的整數倍。
2)mov w0,#0x1
把操作數1賦值給寄存器w0。
3)str w0,[sp,#12]
把w0寄存器的值傳送到棧頂開始的第12字節對應的內存中。也就是給變量a賦值。
4)mov w0,#0x2
把操作數2賦值給寄存器w0。
5)str w0,[sp,#8]
把w0寄存器的值傳送到棧頂開始的第8字節對應的內存中,也就是給變量b賦值。
6)str wzr,[sp,#4]
把零寄存器的值傳送到棧頂開始的第4字節對應的內存中,也就是給變量c賦值。零寄存器的值總是0。
7)ldr w1,[sp,#12]
把棧頂開始的第12字節對應的內存數據傳送給w1寄存器,也就是把變量a讀到寄存器w1。
8)ldr w0,[sp,#8]
同上,把變量b讀到寄存器w0。
9)add w0,w1,w0
把w0和w1相加,存到w0寄存器中。
10)str w0,[sp,#4]
把寄存器w0的值寫到變量c中。
11)ldr w0,[sp,#4]
把變量c中的值寫回寄存器w0,w0用來作為返回值寄存器。
12)add sp,sp,#0x10
恢復棧空間,釋放內存。
注意:這里使用了objdump的-S選項,該選項將代碼段反匯編的同時,將反匯編代碼和源代碼交替顯示。該選項需要gcc在編譯時使用-g的選項。
2.x86架構
針對5.1.1節在x86架構下編譯的程序x86_demo,通過反匯編工具查看它的匯編指令,詳細步驟如下:
步驟1:安裝反匯編工具objdump。objdump在工具包binutils中,可以通過yum安裝該工具包,命令如下:
yum install -y binutils
步驟2:反編譯x86_demo,命令及回顯如下(只保留與main方法相關的匯編代碼):

對main函數的每行代碼簡要解釋如下:
1)push %rbp
將調用函數的棧幀棧底地址入棧,即將bp寄存器的值壓入調用棧中。
2)mov %rsp,%rbp
建立新的棧幀,將main函數的棧幀棧底地址放入bp寄存器中。sp和bp是兩個指針寄存器,一般的函數調用都會使用上述兩個指令。
3)movl $0x1,-0x4(%rbp)
把1傳送給變量a(整型變量占用4字節,所以這里是-0x4)。
4)movl $0x2,-0x8(%rbp)
把2傳送給變量b。
5)movl $0x0,-0xc(%rbp)
把0傳送給變量c。
6)mov -0x8(%rbp),%eax
把變量b的值傳送給eax寄存器。
7)mov -0x4(%rbp),%edx
把變量a的值傳送給edx寄存器。
8)add %edx,%eax
edx和eax寄存器相加并存入eax寄存器。
9)mov %eax,-0xc(%rbp)
把eax寄存器的值傳送給變量c。
10)mov -0xc(%rbp),%eax
把變量c的值傳送給寄存器eax,eax作為返回值寄存器。
11)pop %rbp
恢復上一棧幀的bp。
- MySQL數據庫管理實戰
- Python數據分析基礎
- Visual Basic編程:從基礎到實踐(第2版)
- Android 7編程入門經典:使用Android Studio 2(第4版)
- Internet of Things with the Arduino Yún
- jQuery從入門到精通 (軟件開發視頻大講堂)
- Apache Mahout Clustering Designs
- 區塊鏈技術與應用
- Babylon.js Essentials
- INSTANT Yii 1.1 Application Development Starter
- Python程序設計與算法基礎教程(第2版)(微課版)
- Training Systems Using Python Statistical Modeling
- 零基礎C#學習筆記
- 軟件測試分析與實踐
- Mastering ASP.NET Core 2.0