为什么要学习汇编

iOS汇编

汇编是严重依赖机器的,架构不一样,汇编指令也不一样 一般来说,我们先学习真机设备的汇编

如何学好汇编

1.寄存器 2.指令 3.堆栈

寄存器

通用寄存器

x0 ~ x7通常拿来存放函数的参数,更多的参数使用堆栈来传递,寄存器运行速度比堆栈更快 x0 通常拿来作为函数的返回值

连接真机状态下,在touchBegin方法断点

register read x0

register :寄存器

register read w0
register write x0 0x1000000001

write 写东西,x0 被写入 0x1000000001

register read 

会列出所有寄存器

x19 = 0x000000014ed50410
x20 = 0x000000014ee87d00
x21 = 0x000000014ed08d00
x22 = 0x0000000188ad276e  "touchesBegan:withEvent:"
x23 = 0x000000014ed47890
x24 = 0x000000014ee3cb80
x25 = 0x000000014ed47890
x26 = 0x000000014ed08d00
x27 = 0x0000000188acdbc6  "layer"
x28 = 0x000000014ed50410
fp = 0x000000016fd5dea0
sp = 0x000000016fd5de70
pc = 0x00000001000a594c  -[ViewController touchesBegan:withEvent:] + 104 at ViewController.m:62
21 registers were unavailable.

如何学习写汇编代码

外部建立文件学习汇编代码

1.新建汇编文件

新建iOS ->Other -> Empty

汇编是.asm ,一般我们用.s 比如arm.s

2.新建头文件arm.h

声明函数

void test();

3.调用汇编函数

在main函数调用

int main(int argc, char * argv[]) {
    @autoreleasepool {
        test();
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

汇编指令学习

第一条汇编指令:返回指令ret

mov 数据传输指令(全称move),用法示例

// 声明它是代码段 .data 就是数据段, .stack就是栈段
.text
; 默认函数是私有的,需要声明成全局的函数
.global _test

; 调用test()函数,底层会做转换,变成_test
_test:
; 将8赋值给x0
mov x0, 8
ret

注:

汇编注释用; 也可以用// 汇编不区分大小写,写mov == MOV

ADD指令

ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中.操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或是一个立即数.

加法add指令示例

mov x0, #0x1
mov x1, #0x2
add x2, x0, x1

断点停在汇编后,控制台使用lldb指令查看

si
register read x2
x2 = 0x0000000000000003

减法sub指令示例

mov x0,  #0x5
mov x1,  #0x2
sub x2, x0, x1

相当于x0-x1赋值给x2

lldb指令查看

register read x2
x2 = 0x0000000000000003

加法函数示例

.h声明

int add(int a,int b);

arm.s文件实现

// add函数的实现
_add:
add x0, x0, x1
ret

声明为全局函数

.global _test ,_add

外部调用示例

NSLog(@"%d",add(1, 2));

注意: x0 通常拿来作为函数的返回值

x0 ~ x7通常拿来存放函数的参数,更多的参数使用堆栈来传递,寄存器运行速度比堆栈更快

add 指令不可以使用 =,而是使用

函数后面必须要有ret不然会继续往下走,直到遇到ret