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 <printf@plt> //跳转到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 <printf@plt>
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