cmp(Compare)比较指令
CMP 把一个寄存器的内容和另一个寄存器的内容或立即数进行比较。但不存储结果,只是正确的更改标志。
一般CMP做完判断后会进行跳转,后面通常会跟上B指令!
- BL 标号:跳转到标号处执行
- B.GT 标号:比较结果是大于(greater than),执行标号,否则不跳转
- B.GE 标号:比较结果是大于等于(greater than or equal to),执行标号,否则不跳转
- B.EQ 标号:比较结果是等于,执行标号,否则不跳转
- B.HI 标号:比较结果是无符号大于,执行标号,否则不跳转
Switch
1、假设switch语句的分支比较少的时候(例如3,少于4的时候没有意义)没有必要使用此结构,相当于if。
__text:00000001000067F8 EXPORT _funA
__text:00000001000067F8 _funA ; CODE XREF: _main+20↓p
__text:00000001000067F8
__text:00000001000067F8 var_24 = -0x24
__text:00000001000067F8 var_20 = -0x20
__text:00000001000067F8 var_1C = -0x1C
__text:00000001000067F8 var_18 = -0x18
__text:00000001000067F8 var_14 = -0x14
__text:00000001000067F8 var_10 = -0x10
__text:00000001000067F8 var_C = -0xC
__text:00000001000067F8 var_8 = -8
__text:00000001000067F8 var_4 = -4
__text:00000001000067F8 var_s0 = 0
__text:00000001000067F8
__text:00000001000067F8 SUB SP, SP, #0x40
__text:00000001000067FC STP X29, X30, [SP,#0x30+var_s0]
__text:0000000100006800 ADD X29, SP, #0x30
__text:0000000100006804 STUR W0, [X29,#var_4]
__text:0000000100006808 LDUR W0, [X29,#var_4]
__text:000000010000680C MOV X8, X0
__text:0000000100006810 SUBS W0, W0, #1
__text:0000000100006814 STUR W8, [X29,#var_8]
__text:0000000100006818 STUR W0, [X29,#var_C]
__text:000000010000681C B.EQ loc_10000684C
__text:0000000100006820 B loc_100006824
__text:0000000100006824 ; ---------------------------------------------------------------------------
__text:0000000100006824
__text:0000000100006824 loc_100006824 ; CODE XREF: _funA+28↑j
__text:0000000100006824 LDUR W8, [X29,#var_8]
__text:0000000100006828 SUBS W9, W8, #2
__text:000000010000682C STUR W9, [X29,#var_10]
__text:0000000100006830 B.EQ loc_100006860
__text:0000000100006834 B loc_100006838
__text:0000000100006838 ; ---------------------------------------------------------------------------
__text:0000000100006838
__text:0000000100006838 loc_100006838 ; CODE XREF: _funA+3C↑j
__text:0000000100006838 LDUR W8, [X29,#var_8]
__text:000000010000683C SUBS W9, W8, #3
__text:0000000100006840 STUR W9, [X29,#var_14]
__text:0000000100006844 B.EQ loc_100006874
__text:0000000100006848 B loc_100006888
__text:000000010000684C ; ---------------------------------------------------------------------------
__text:000000010000684C
__text:000000010000684C loc_10000684C ; CODE XREF: _funA+24↑j
__text:000000010000684C ADRP X0, #asc_100007F08@PAGE ; "打坐"
__text:0000000100006850 ADD X0, X0, #asc_100007F08@PAGEOFF ; "打坐"
__text:0000000100006854 BL _printf
__text:0000000100006858 STR W0, [SP,#0x30+var_18]
__text:000000010000685C B loc_100006898
__text:0000000100006860 ; ---------------------------------------------------------------------------
__text:0000000100006860
__text:0000000100006860 loc_100006860 ; CODE XREF: _funA+38↑j
__text:0000000100006860 ADRP X0, #asc_100007F0F@PAGE ; "加红"
__text:0000000100006864 ADD X0, X0, #asc_100007F0F@PAGEOFF ; "加红"
__text:0000000100006868 BL _printf
__text:000000010000686C STR W0, [SP,#0x30+var_1C]
__text:0000000100006870 B loc_100006898
__text:0000000100006874 ; ---------------------------------------------------------------------------
__text:0000000100006874
__text:0000000100006874 loc_100006874 ; CODE XREF: _funA+4C↑j
__text:0000000100006874 ADRP X0, #asc_100007F16@PAGE ; "加蓝"
__text:0000000100006878 ADD X0, X0, #asc_100007F16@PAGEOFF ; "加蓝"
__text:000000010000687C BL _printf
__text:0000000100006880 STR W0, [SP,#0x30+var_20]
__text:0000000100006884 B loc_100006898
__text:0000000100006888 ; ---------------------------------------------------------------------------
__text:0000000100006888
__text:0000000100006888 loc_100006888 ; CODE XREF: _funA+50↑j
__text:0000000100006888 ADRP X0, #asc_100007F1D@PAGE ; "啥都不干"
__text:000000010000688C ADD X0, X0, #asc_100007F1D@PAGEOFF ; "啥都不干"
__text:0000000100006890 BL _printf
__text:0000000100006894 STR W0, [SP,#0x30+var_24]
__text:0000000100006898
__text:0000000100006898 loc_100006898 ; CODE XREF: _funA+64↑j
__text:0000000100006898 ; _funA+78↑j ...
__text:0000000100006898 LDP X29, X30, [SP,#0x30+var_s0]
__text:000000010000689C ADD SP, SP, #0x40
__text:00000001000068A0 RET
__text:00000001000068A0 ; End of function _funA
2、各个分支常量的差值较大的时候,编译器会在效率还是内存进行取舍,这个时候编译器还是会编译成类似于if,else的结构。
__text:00000001000067C8 EXPORT _funA
__text:00000001000067C8 _funA ; CODE XREF: _main+20↓p
__text:00000001000067C8
__text:00000001000067C8 var_2C = -0x2C
__text:00000001000067C8 var_28 = -0x28
__text:00000001000067C8 var_24 = -0x24
__text:00000001000067C8 var_20 = -0x20
__text:00000001000067C8 var_1C = -0x1C
__text:00000001000067C8 var_18 = -0x18
__text:00000001000067C8 var_14 = -0x14
__text:00000001000067C8 var_10 = -0x10
__text:00000001000067C8 var_C = -0xC
__text:00000001000067C8 var_8 = -8
__text:00000001000067C8 var_4 = -4
__text:00000001000067C8 var_s0 = 0
__text:00000001000067C8
__text:00000001000067C8 SUB SP, SP, #0x40
__text:00000001000067CC STP X29, X30, [SP,#0x30+var_s0]
__text:00000001000067D0 ADD X29, SP, #0x30
__text:00000001000067D4 STUR W0, [X29,#var_4]
__text:00000001000067D8 LDUR W0, [X29,#var_4]
__text:00000001000067DC MOV X8, X0
__text:00000001000067E0 SUBS W0, W0, #1
__text:00000001000067E4 STUR W8, [X29,#var_8]
__text:00000001000067E8 STUR W0, [X29,#var_C]
__text:00000001000067EC B.EQ loc_100006830
__text:00000001000067F0 B loc_1000067F4
__text:00000001000067F4 ; ---------------------------------------------------------------------------
__text:00000001000067F4
__text:00000001000067F4 loc_1000067F4 ; CODE XREF: _funA+28↑j
__text:00000001000067F4 LDUR W8, [X29,#var_8]
__text:00000001000067F8 SUBS W9, W8, #4
__text:00000001000067FC STUR W9, [X29,#var_10]
__text:0000000100006800 B.EQ loc_10000686C
__text:0000000100006804 B loc_100006808
__text:0000000100006808 ; ---------------------------------------------------------------------------
__text:0000000100006808
__text:0000000100006808 loc_100006808 ; CODE XREF: _funA+3C↑j
__text:0000000100006808 LDUR W8, [X29,#var_8]
__text:000000010000680C SUBS W9, W8, #0xC8
__text:0000000100006810 STUR W9, [X29,#var_14]
__text:0000000100006814 B.EQ loc_100006844
__text:0000000100006818 B loc_10000681C
__text:000000010000681C ; ---------------------------------------------------------------------------
__text:000000010000681C
__text:000000010000681C loc_10000681C ; CODE XREF: _funA+50↑j
__text:000000010000681C LDUR W8, [X29,#var_8]
__text:0000000100006820 SUBS W9, W8, #0x1F4
__text:0000000100006824 STR W9, [SP,#0x30+var_18]
__text:0000000100006828 B.EQ loc_100006858
__text:000000010000682C B loc_100006880
__text:0000000100006830 ; ---------------------------------------------------------------------------
__text:0000000100006830
__text:0000000100006830 loc_100006830 ; CODE XREF: _funA+24↑j
__text:0000000100006830 ADRP X0, #asc_100007F00@PAGE ; "打坐"
__text:0000000100006834 ADD X0, X0, #asc_100007F00@PAGEOFF ; "打坐"
__text:0000000100006838 BL _printf
__text:000000010000683C STR W0, [SP,#0x30+var_1C]
__text:0000000100006840 B loc_100006890
__text:0000000100006844 ; ---------------------------------------------------------------------------
__text:0000000100006844
__text:0000000100006844 loc_100006844 ; CODE XREF: _funA+4C↑j
__text:0000000100006844 ADRP X0, #asc_100007F07@PAGE ; "加红"
__text:0000000100006848 ADD X0, X0, #asc_100007F07@PAGEOFF ; "加红"
__text:000000010000684C BL _printf
__text:0000000100006850 STR W0, [SP,#0x30+var_20]
__text:0000000100006854 B loc_100006890
__text:0000000100006858 ; ---------------------------------------------------------------------------
__text:0000000100006858
__text:0000000100006858 loc_100006858 ; CODE XREF: _funA+60↑j
__text:0000000100006858 ADRP X0, #asc_100007F0E@PAGE ; "加蓝"
__text:000000010000685C ADD X0, X0, #asc_100007F0E@PAGEOFF ; "加蓝"
__text:0000000100006860 BL _printf
__text:0000000100006864 STR W0, [SP,#0x30+var_24]
__text:0000000100006868 B loc_100006890
__text:000000010000686C ; ---------------------------------------------------------------------------
__text:000000010000686C
__text:000000010000686C loc_10000686C ; CODE XREF: _funA+38↑j
__text:000000010000686C ADRP X0, #asc_100007F15@PAGE ; "摆摊"
__text:0000000100006870 ADD X0, X0, #asc_100007F15@PAGEOFF ; "摆摊"
__text:0000000100006874 BL _printf
__text:0000000100006878 STR W0, [SP,#0x30+var_28]
__text:000000010000687C B loc_100006890
__text:0000000100006880 ; ---------------------------------------------------------------------------
__text:0000000100006880
__text:0000000100006880 loc_100006880 ; CODE XREF: _funA+64↑j
__text:0000000100006880 ADRP X0, #asc_100007F1C@PAGE ; "啥都不干"
__text:0000000100006884 ADD X0, X0, #asc_100007F1C@PAGEOFF ; "啥都不干"
__text:0000000100006888 BL _printf
__text:000000010000688C STR W0, [SP,#0x30+var_2C]
__text:0000000100006890
__text:0000000100006890 loc_100006890 ; CODE XREF: _funA+78↑j
__text:0000000100006890 ; _funA+8C↑j ...
__text:0000000100006890 LDP X29, X30, [SP,#0x30+var_s0]
__text:0000000100006894 ADD SP, SP, #0x40
__text:0000000100006898 RET
__text:0000000100006898 ; End of function _funA
3、在分支比较多的时候:在编译的时候会生成一个表(跳转表每个地址四个字节)。
__text:00000001000067DC EXPORT _funA
__text:00000001000067DC _funA ; CODE XREF: _main+20↓p
__text:00000001000067DC
__text:00000001000067DC var_28 = -0x28
__text:00000001000067DC var_24 = -0x24
__text:00000001000067DC var_20 = -0x20
__text:00000001000067DC var_1C = -0x1C
__text:00000001000067DC var_18 = -0x18
__text:00000001000067DC var_14 = -0x14
__text:00000001000067DC var_10 = -0x10
__text:00000001000067DC var_4 = -4
__text:00000001000067DC var_s0 = 0
__text:00000001000067DC
__text:00000001000067DC SUB SP, SP, #0x40
__text:00000001000067E0 STP X29, X30, [SP,#0x30+var_s0]
__text:00000001000067E4 ADD X29, SP, #0x30
__text:00000001000067E8 STUR W0, [X29,#var_4]
__text:00000001000067EC LDUR W0, [X29,#var_4]
__text:00000001000067F0 SUBS W0, W0, #1 ; switch 4 cases
__text:00000001000067F4 MOV X8, X0
__text:00000001000067F8 SUBS W0, W0, #3
__text:00000001000067FC STUR X8, [X29,#var_10]
__text:0000000100006800 STUR W0, [X29,#var_14]
__text:0000000100006804 B.HI def_10000681C ; jumptable 000000010000681C default case
__text:0000000100006808 ADRP X8, #jpt_10000681C@PAGE
__text:000000010000680C ADD X8, X8, #jpt_10000681C@PAGEOFF
__text:0000000100006810 LDUR X9, [X29,#var_10]
__text:0000000100006814 LDRSW X10, [X8,X9,LSL#2]
__text:0000000100006818 ADD X8, X10, X8
__text:000000010000681C BR X8 ; switch jump
__text:0000000100006820 ; ---------------------------------------------------------------------------
__text:0000000100006820
__text:0000000100006820 loc_100006820 ; CODE XREF: _funA+40↑j
__text:0000000100006820 ; DATA XREF: __text:jpt_10000681C↓o
__text:0000000100006820 ADRP X0, #asc_100007F00@PAGE ; jumptable 000000010000681C case 1
__text:0000000100006824 ADD X0, X0, #asc_100007F00@PAGEOFF ; "打坐"
__text:0000000100006828 BL _printf
__text:000000010000682C STR W0, [SP,#0x30+var_18]
__text:0000000100006830 B loc_100006880
__text:0000000100006834 ; ---------------------------------------------------------------------------
__text:0000000100006834
__text:0000000100006834 loc_100006834 ; CODE XREF: _funA+40↑j
__text:0000000100006834 ; DATA XREF: __text:0000000100006890↓o
__text:0000000100006834 ADRP X0, #asc_100007F07@PAGE ; jumptable 000000010000681C case 2
__text:0000000100006838 ADD X0, X0, #asc_100007F07@PAGEOFF ; "加红"
__text:000000010000683C BL _printf
__text:0000000100006840 STR W0, [SP,#0x30+var_1C]
__text:0000000100006844 B loc_100006880
__text:0000000100006848 ; ---------------------------------------------------------------------------
__text:0000000100006848
__text:0000000100006848 loc_100006848 ; CODE XREF: _funA+40↑j
__text:0000000100006848 ; DATA XREF: __text:0000000100006894↓o
__text:0000000100006848 ADRP X0, #asc_100007F0E@PAGE ; jumptable 000000010000681C case 3
__text:000000010000684C ADD X0, X0, #asc_100007F0E@PAGEOFF ; "加蓝"
__text:0000000100006850 BL _printf
__text:0000000100006854 STR W0, [SP,#0x30+var_20]
__text:0000000100006858 B loc_100006880
__text:000000010000685C ; ---------------------------------------------------------------------------
__text:000000010000685C
__text:000000010000685C loc_10000685C ; CODE XREF: _funA+40↑j
__text:000000010000685C ; DATA XREF: __text:0000000100006898↓o
__text:000000010000685C ADRP X0, #asc_100007F15@PAGE ; jumptable 000000010000681C case 4
__text:0000000100006860 ADD X0, X0, #asc_100007F15@PAGEOFF ; "摆摊"
__text:0000000100006864 BL _printf
__text:0000000100006868 STR W0, [SP,#0x30+var_24]
__text:000000010000686C B loc_100006880
__text:0000000100006870 ; ---------------------------------------------------------------------------
__text:0000000100006870
__text:0000000100006870 def_10000681C ; CODE XREF: _funA+28↑j
__text:0000000100006870 ADRP X0, #asc_100007F1C@PAGE ; jumptable 000000010000681C default case
__text:0000000100006874 ADD X0, X0, #asc_100007F1C@PAGEOFF ; "啥都不干"
__text:0000000100006878 BL _printf
__text:000000010000687C STR W0, [SP,#0x30+var_28]
__text:0000000100006880
__text:0000000100006880 loc_100006880 ; CODE XREF: _funA+54↑j
__text:0000000100006880 ; _funA+68↑j ...
__text:0000000100006880 LDP X29, X30, [SP,#0x30+var_s0]
__text:0000000100006884 ADD SP, SP, #0x40
__text:0000000100006888 RET
__text:0000000100006888 ; End of function _funA
还原高级代码(if...else...)
OC代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int g = 12;
void func(int a, int b) {
if (a > b) {
g = a;
} else {
g = b;
}
}
int main(int argc, char * argv[]) {
func(1, 2);
return 0;
}
main函数汇编分析
__text:00000001000068CC _main
__text:00000001000068CC
__text:00000001000068CC var_10 = -0x10
__text:00000001000068CC var_8 = -8
__text:00000001000068CC var_4 = -4
__text:00000001000068CC var_s0 = 0
__text:00000001000068CC
__text:00000001000068CC SUB SP, SP, #0x20
__text:00000001000068D0 STP X29, X30, [SP,#0x10+var_s0]
__text:00000001000068D4 ADD X29, SP, #0x10
__text:00000001000068D8 MOV W8, #1
int W8 = 1;
__text:00000001000068DC MOV W9, #2
int W9 = 2;
__text:00000001000068E0 STUR WZR, [X29,#var_4]
__text:00000001000068E4 STR W0, [SP,#0x10+var_8]
int var_8 = W0;
__text:00000001000068E8 STR X1, [SP,#0x10+var_10]
int var_10 = X1;
__text:00000001000068EC MOV X0, X8
int X0 = X8;
__text:00000001000068F0 MOV X1, X9
int X1 = X9;
__text:00000001000068F4 BL _func
跳转到func函数
__text:00000001000068F8 MOV W8, #0
__text:00000001000068FC MOV X0, X8
__text:0000000100006900 LDP X29, X30, [SP,#0x10+var_s0]
__text:0000000100006904 ADD SP, SP, #0x20
__text:0000000100006908 RET
__text:0000000100006908 ; End of function _main
由此分析:函数名为func,并且带两个参数,参数类型为int。
func函数汇编分析
//__text:0000000100006884 EXPORT _func
//__text:0000000100006884 _func ; CODE XREF: _main+28↓p
//__text:0000000100006884
//__text:0000000100006884 var_8 = -8
//__text:0000000100006884 var_4 = -4
//__text:0000000100006884
//__text:0000000100006884 SUB SP, SP, #0x10
int g = 12;//具体的值需要动态调试得到
void func(int a, int b) {
//__text:0000000100006888 STR W0, [SP,#0x10+var_4]
int var_4 = a;
//__text:000000010000688C STR W1, [SP,#0x10+var_8]
int var_8 = b;
//__text:0000000100006890 LDR W0, [SP,#0x10+var_4]
int W0 = var_4;
//__text:0000000100006894 LDR W1, [SP,#0x10+var_8]
int W1 = var_8;
//__text:0000000100006898 CMP W0, W1
//__text:000000010000689C B.LE loc_1000068B4
if (W0 > W1) {
//__text:00000001000068A0 ADRP X8, #_g@PAGE
//__text:00000001000068A4 ADD X8, X8, #_g@PAGEOFF
int* X8 = &g;
//__text:00000001000068A8 LDR W9, [SP,#0x10+var_4]
int W9 = var_4;
//__text:00000001000068AC STR W9, [X8]
* X8 = W9;
} else {
//__text:00000001000068B4 ADRP X8, #_g@PAGE
//__text:00000001000068B8 ADD X8, X8, #_g@PAGEOFF
int* X8 = &g;
//__text:00000001000068BC LDR W9, [SP,#0x10+var_8]
int W9 = var_8;
//__text:00000001000068C0 STR W9, [X8]
* X8 = W9;
}
//__text:00000001000068C4 ADD SP, SP, #0x10
//__text:00000001000068C8 RET
//__text:00000001000068C8 ; End of function _func
}
最后再做下优化就是OC的代码了。