iOS-常见的汇编指令
2020-09-22 本文已影响0人
泽泽伐木类
前言
在我们iOS底层探索的时候,经常需要阅读一些汇编源码,第一次看到的时候总是一头雾水,本片文章就介绍一些常见的汇编指令。
指令
- mov:将某一个寄存器的值复制到另一个寄存器(只能在寄存器与寄存器或者寄存器与常量之间传值,不能用于内存地址)
mov x1, x0 // 将寄存器x0的值 复制到寄存器 x1
-
add:将某一寄存器的值和另一寄存器的值 相加(
+
) 并将结果保存在另一寄存器中
add x0, x1, x2 // 将寄存器x1 和 x2 相加后保存结果到寄存器x0中
-
sub:将某一寄存器的值和另一寄存器的值 相减(
-
) 并将结果保存在另一寄存器中
sub x0, x1, x2 //将寄存器 x1 和 x2 的值相减后 并将结果保存到 x0
-
and: 将某一寄存器的值和另一寄存器的值 按位与(
&
) 并将结果保存到另一寄存器中
and x0, x0, #0x1 // x0 & 0x1 ,将寄存器x0 的值和常量 1 按位与 后保存到寄存器x0
-
orr : 将某一寄存器的值和另一寄存器的值 按位或(
|
) 并将结果保存到另一寄存器中
orr x0, x0, #0x1 //将寄存器x0的值 与 常量 1 按位或 并将结果保存到x0
- str :将寄存器中的值写入到内存中
str x0, [x0,x8] //将寄存器x0 中的值 保存到栈内存 [x0+x8] 处
- ldr : 将内存中的值读取到寄存器中
ldr x0, [x1,x2] //将寄存器x1 和 x2 的值相加作为地址,取该内存地址的值放入x0中
- cbz : 和 0 比较,如果结果为零就转移(只能跳到后面的指令)
cbz r1, LNilReceiver_f //如果r1 = 0,就跳转到LNilReceiver_f
- cbnz:和非 0 比较,如果结果非零就转移(只能跳到后面的指令)
- cmp: 比较指令
cmp r12, #1
- b :(branch)跳转到某地址(无返回)
b __objc_msgSend_uncached
- bl:跳转到某地址(有返回)
- ret:子程序(函数调用)返回指令,返回地址已默认保存在寄存器 lr (x30)
其他
-
ENTRY:在ARM汇编中,
ENTRY
是一个伪指令,用于指du定汇编程序的入口点。在一个较大型的完整的汇编版程序(多个源权文件组成的工程)中至少要有一个ENTRY
(也可以有多个,当有多个ENTRY
时,程序的真正入口点由链接器指定),但在某一个源文件里最多只能有一个ENTRY
(可以没有)。
ENTRY _objc_msgSend
-
macro:用
.macro
指令你可以定义一个宏,可以把需要重复执行的一段代码,或者是一组指令缩写成一个宏,在 程序调用的时候就可以直接去调用这个宏而使代码更加简洁清晰,此宏由以下3部分构成:
- 头: 在这里可以指定这个宏的名称,并且定义形式参数
- 体: 这里包含的是当这个宏被调用时所需要执行的指令或者语句。
- 尾: 这里用
.endmacro
标识着这个宏的结束。
.macro MethodTableLookup //头部
stmfd sp!, {r0-r3,r7,lr}
add r7, sp, #16
sub sp, #8 // align stack
FP_SAVE
// lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
.if $0 == NORMAL
// receiver already in r0
// selector already in r1
.else
mov r0, r1 // receiver
mov r1, r2 // selector
.endif
mov r2, r9 // class to search
mov r3, #3 // LOOKUP_INITIALIZE | LOOKUP_INITIALIZE
blx _lookUpImpOrForward
mov r12, r0 // r12 = IMP
.if $0 == NORMAL
cmp r12, r12 // set eq for nonstret forwarding
.else
tst r12, r12 // set ne for stret forwarding
.endif
FP_RESTORE
add sp, #8 // align stack
ldmfd sp!, {r0-r3,r7,lr}
.endmacro //尾部
总结
内容正在完善中,仅供参考,如有错误,请在评论区指正Thanks♪(・ω・)ノ