403be8: 52800020 mov w0, #0x1 // #1
403bec: 52800001 mov w1, #0x0 // #0
403bf0: 7100077f cmp w27, #0x1 // w27=rep
403bf4: 54000aac b.gt 403d48 <ferror@plt+0x1e68>
if (rep > 1) {
// b.gt 403d48
}
/*403d48: 2a0003f7 mov w23, w0 // div=w23=w0=1
403d4c: 0b000800 add w0, w0, w0, lsl #2 // w0=1+1<<2=1+4=5, 乘法第一步,加法
403d50: 2a0103f9 mov w25, w1 // w25=w1=0
403d54: 11000421 add w1, w1, #0x1 // digits=w1=0+1=1
403d58: 531f7800 lsl w0, w0, #1 // w0=5<<1=10, div *= 10, 乘法第二步,左位移
403d5c: 1ac00f62 sdiv w2, w27, w0 // w2=w27/w0=rep/div
403d60: 35ffff42 cbnz w2, 403d48 <ferror@plt+0x1e68>
digits = 0;
for (div = 1; x / div; div *= 10) // 调试时跟踪指令解开了x/1之谜。digits先加1,即简化了x/1这一步。
digits++; // 对于这步的优化条件,依据为进来前的cmp指令比较大于1。
也可写成:
digits = 1;
for (div = 10; x / div; div *= 10)
digits++
调试:
Breakpoint 1, 0x0000000000403d48 in ?? ()
=> 0x0000000000403d48: f7 03 00 2a mov w23, w0
(gdb) watch $w0
Watchpoint 2: $w0
(gdb) n
0x0000000000403d4c in ?? ()
=> 0x0000000000403d4c: 00 08 00 0b add w0, w0, w0, lsl #2
(gdb) watch $w23
Watchpoint 3: $w23
(gdb) n
Watchpoint 2: $w0
Old value = 1
New value = 5
0x0000000000403d50 in ?? ()
=> 0x0000000000403d50: f9 03 01 2a mov w25, w1
(gdb)
0x0000000000403d54 in ?? ()
=> 0x0000000000403d54: 21 04 00 11 add w1, w1, #0x1
(gdb)
0x0000000000403d58 in ?? ()
=> 0x0000000000403d58: 00 78 1f 53 lsl w0, w0, #1
(gdb)
Watchpoint 2: $w0
Old value = 5
New value = 10
0x0000000000403d5c in ?? ()
=> 0x0000000000403d5c: 62 0f c0 1a sdiv w2, w27, w0
(gdb)
0x0000000000403d60 in ?? ()
=> 0x0000000000403d60: 42 ff ff 35 cbnz w2, 0x403d48
(gdb)
Breakpoint 1, 0x0000000000403d48 in ?? ()
=> 0x0000000000403d48: f7 03 00 2a mov w23, w0
(gdb)
Watchpoint 3: $w23
Old value = 1
New value = 10
0x0000000000403d4c in ?? ()
=> 0x0000000000403d4c: 00 08 00 0b add w0, w0, w0, lsl #2
(gdb)
Watchpoint 2: $w0
Old value = 10
New value = 50
0x0000000000403d50 in ?? ()
=> 0x0000000000403d50: f9 03 01 2a mov w25, w1
(gdb)
0x0000000000403d54 in ?? ()
=> 0x0000000000403d54: 21 04 00 11 add w1, w1, #0x1
(gdb)
0x0000000000403d58 in ?? ()
=> 0x0000000000403d58: 00 78 1f 53 lsl w0, w0, #1
(gdb)
Watchpoint 2: $w0
Old value = 50
New value = 100
0x0000000000403d5c in ?? ()
=> 0x0000000000403d5c: 62 0f c0 1a sdiv w2, w27, w0