C IN ARM64 彙編基礎-變數與表示式-基於The C Programming Language - Second Edition
阿新 • • 發佈:2019-01-09
C原始碼:
#include <stdio.h> /* print Fahrenheit-Celsius table for fahr = 0, 20, ..., 300 */ main() { int fahr, celsius; int lower, upper, step; lower = 0; /* lower limit of temperature scale */ upper = 300; /* upper limit */ step = 20; /* step size */ fahr = lower; while (fahr <= upper) { celsius = 5 * (fahr-32) / 9; printf("%d\t%d\n", fahr, celsius); fahr = fahr + step; } }
對應彙編程式碼:
00000000000005b0 <main>: 5b0: a9bd57f6 stp x22, x21, [sp,#-48]! //申請48bytes的棧空間,sp = sp - 48,stp指令為儲存一對資料,依次儲存x22、x21到sp-48處 5b4: a9014ff4 stp x20, x19, [sp,#16] //sp+16的位置儲存x20、x19 5b8: a9027bfd stp x29, x30, [sp,#32] //sp+32的位置儲存x29、x30 5bc: 910083fd add x29, sp, #0x20 //x29,也就是fp指向sp+32 5c0: 52a71c76 mov w22, #0x38e30000 // #954400768//w22儲存#0x38e30000,4個byte 5c4: 90000014 adrp x20, 0 <abitag-0x200> 5c8: 2a1f03f3 mov w19, wzr //w19儲存0暫存器的值0 5cc: 128013f5 mov w21, #0xffffff60 // #-160 5d0: 7291c736 movk w22, #0x8e39 5d4: 91186294 add x20, x20, #0x618 5d8: 9b367ea8 smull x8, w21, w22 //smull為64位乘法指令 5dc: d37ffd09 lsr x9, x8, #63 5e0: 9361fd08 asr x8, x8, #33 5e4: 0b090102 add w2, w8, w9 5e8: aa1403e0 mov x0, x20 5ec: 2a1303e1 mov w1, w19 5f0: 97ffffc0 bl 4f0 <
[email protected]> //跳轉到print函式 5f4: 11005273 add w19, w19, #0x14 //w19暫存器中的內容加0x14 5f8: 110192b5 add w21, w21, #0x64 5fc: 7104b67f cmp w19, #0x12d //將w19暫存器中的值與0x12d進行比較 600: 54fffecb b.lt 5d8 <main+0x28> //小於的話跳轉到5d8 604: a9427bfd ldp x29, x30, [sp,#32] 608: a9414ff4 ldp x20, x19, [sp,#16] 60c: 2a1f03e0 mov w0, wzr 610: a8c357f6 ldp x22, x21, [sp],#48 614: d65f03c0 ret
彙編中全程未看見變數與常量的值都在哪,看起來有點懵,這種可以找一下關鍵點。
關鍵點如下:
首先有個while迴圈,fahr <= upper成立時跳轉到5d8,5d8處是乘法指令,是在執行celsius = 5 * (fahr-32) / 9計算。所以開始處的暫存器x21、x22是儲存乘法運算用到的臨時變數的,對x21、x22的操作是如何對應到celsius = 5 * (fahr-32) / 9的,這裡就不詳細分析了,涉及到的細節比較多。
上面的彙編原始碼是優化後的,一般預設的情況下都是有優化的,我們在解native問題時拿到的symbols也是優化過的,有了編譯優化會增加問題的分析難度。下面是未優化過的彙編原始碼,與C原始碼是高度吻合的,也很好分析。
00000000000005b0 <main>:
5b0: d100c3ff sub sp, sp, #0x30
5b4: a9027bfd stp x29, x30, [sp,#32]
5b8: 910083fd add x29, sp, #0x20
5bc: 52800288 mov w8, #0x14 // #20
5c0: 52802589 mov w9, #0x12c // #300
5c4: b81fc3bf stur wzr, [x29,#-4]
5c8: b90013ff str wzr, [sp,#16]
5cc: b9000fe9 str w9, [sp,#12]
5d0: b9000be8 str w8, [sp,#8]
5d4: b94013e8 ldr w8, [sp,#16]
5d8: b81f83a8 stur w8, [x29,#-8]
5dc: b85f83a8 ldur w8, [x29,#-8]
5e0: b9400fe9 ldr w9, [sp,#12]
5e4: 6b09011f cmp w8, w9
5e8: 5400026c b.gt 634 <main+0x84>
5ec: 528000a8 mov w8, #0x5 // #5
5f0: b85f83a9 ldur w9, [x29,#-8]
5f4: 51008129 sub w9, w9, #0x20
5f8: 1b097d08 mul w8, w8, w9
5fc: 52800129 mov w9, #0x9 // #9
600: 1ac90d08 sdiv w8, w8, w9
604: b81f43a8 stur w8, [x29,#-12]
608: b85f83a1 ldur w1, [x29,#-8]
60c: b85f43a2 ldur w2, [x29,#-12]
610: 90000000 adrp x0, 0 <abitag-0x200>
614: 91191000 add x0, x0, #0x644
618: 97ffffb6 bl 4f0 <[email protected]>
61c: b85f83a8 ldur w8, [x29,#-8]
620: b9400be9 ldr w9, [sp,#8]
624: 0b090108 add w8, w8, w9
628: b81f83a8 stur w8, [x29,#-8]
62c: b90007e0 str w0, [sp,#4]
630: 17ffffeb b 5dc <main+0x2c>
634: b85fc3a0 ldur w0, [x29,#-4]
638: a9427bfd ldp x29, x30, [sp,#32]
63c: 9100c3ff add sp, sp, #0x30
640: d65f03c0 ret