cmp(Compare)比较指令
CMP 把一个寄存器的内容和另一个寄存器的内容或立即数进行比较。但不存储结果,只是正确的更改标志。
一般CMP做完判断后会进行跳转,后面通常会跟上B指令!
- BL 标号:跳转到标号处执行
- B.GT 标号:比较结果是大于(greater than),执行标号,否则不跳转
- B.GE 标号:比较结果是大于等于(greater than or equal to),执行标号,否则不跳转
- B.EQ 标号:比较结果是等于,执行标号,否则不跳转
- B.HI 标号:比较结果是无符号大于,执行标号,否则不跳转
B.LE: 小于等于,写成(>){}(汇编中是反的 如果是LE直接写成>就行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
__text:00000001000068B0 var_8 = -8 __text:00000001000068B0 var_4 = -4 __text:00000001000068B0 __text:00000001000068B0 SUB SP, SP, #0x10 __text:00000001000068B4 STR W0, [SP,#0x10+var_4] __text:00000001000068B8 STR W1, [SP,#0x10+var_8] __text:00000001000068BC LDR W0, [SP,#0x10+var_4] __text:00000001000068C0 LDR W1, [SP,#0x10+var_8] __text:00000001000068C4 CMP W0, W1 __text:00000001000068C8 B.LE loc_1000068E0 #小于等于跳loc_1000068E0否则执行下面 __text:00000001000068CC ADRP X8, #_global@PAGE __text:00000001000068D0 ADD X8, X8, #_global@PAGEOFF __text:00000001000068D4 LDR W9, [SP,#0x10+var_4] __text:00000001000068D8 STR W9, [X8] __text:00000001000068DC B loc_1000068F0 __text:00000001000068E0 ; --------------------------------------------------------------------------- __text:00000001000068E0 __text:00000001000068E0 loc_1000068E0 ; CODE XREF: _funTemp+18↑j __text:00000001000068E0 ADRP X8, #_global@PAGE __text:00000001000068E4 ADD X8, X8, #_global@PAGEOFF __text:00000001000068E8 LDR W9, [SP,#0x10+var_8] __text:00000001000068EC STR W9, [X8] __text:00000001000068F0 __text:00000001000068F0 loc_1000068F0 ; CODE XREF: _funTemp+2C↑j __text:00000001000068F0 ADD SP, SP, #0x10 __text:00000001000068F4 RET |
分析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
//__text:00000001000068B0 var_8 = -8 //__text:00000001000068B0 var_4 = -4 //__text:00000001000068B0 //__text:00000001000068B0 SUB SP, SP, #0x10 #确认2个参数 int global = 20; #这里20可以通过lldb调试得到 void funTemp(int a, int b) { //__text:00000001000068B4 STR W0, [SP,#0x10+var_4] int var_4 = a; #(w0就是a) //__text:00000001000068B8 STR W1, [SP,#0x10+var_8] int var_8 = b; #(w1就是b) //__text:00000001000068BC LDR W0, [SP,#0x10+var_4] int w0 = var_4; //__text:00000001000068C0 LDR W1, [SP,#0x10+var_8] int w1 = var_8; //__text:00000001000068C4 CMP W0, W1 if (a > b) #(w0 > w1 由上面式子换算,汇编中真好是相反的判断顺序) { //__text:00000001000068DC B loc_1000068F0 //__text:00000001000068CC ADRP X8, #_global@PAGE //__text:00000001000068D0 ADD X8, X8, #_global@PAGEOFF int* x8 = &global; //__text:00000001000068D4 LDR W9, [SP,#0x10+var_4] int w9 = var_4; //__text:00000001000068D8 STR W9, [X8] *x8 = var_4; #换算后 global = a; //__text:00000001000068E0 ; --------------------------------------------------------------------------- //__text:00000001000068E0 //__text:00000001000068F0 //__text:00000001000068F0 loc_1000068F0 ; CODE XREF: _funTemp+2C↑j //__text:00000001000068F0 ADD SP, SP, #0x10 //__text:00000001000068F4 RET } else { #如果满足就跳 loc_1000068E0 //__text:00000001000068C8 B.LE loc_1000068E0 //__text:00000001000068E0 loc_1000068E0 ; CODE XREF: _funTemp+18↑j //__text:00000001000068E0 ADRP X8, #_global@PAGE //__text:00000001000068E4 ADD X8, X8, #_global@PAGEOFF int* x8 = &global; #(global 是取得地址值) (确认这里有个全局变量global) //__text:00000001000068E8 LDR W9, [SP,#0x10+var_8] int w9 = var_8; //__text:00000001000068EC STR W9, [X8] *x8 = w9; # 也就是global = w9; #再换算 global = b; } } |
优化后:
1 2 3 4 5 6 7 8 9 10 11 12 |
int global = 20; void funTemp(int a, int b) { if (a > b) { global = a; } else { global = b; } } |