官术网_书友最值得收藏!

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。

主站蜘蛛池模板: 新巴尔虎左旗| 凉山| 岫岩| 灵宝市| 兰州市| 宜兰县| 延津县| 山东省| 汉寿县| 沾化县| 许昌县| 喀喇| 资中县| 兴义市| 新蔡县| 衡水市| 离岛区| 襄城县| 于田县| 遵义县| 鞍山市| 南昌县| 精河县| 茌平县| 普兰店市| 涞源县| 开封市| 红河县| 石嘴山市| 丹江口市| 盈江县| 泉州市| 马山县| 四子王旗| 仪陇县| 陇南市| 永兴县| 渑池县| 奉贤区| 莱州市| 南澳县|