09-1-ARM64汇编之基础

本文详细介绍iOS平台上的arm64汇编语言,包括基本指令、寄存器使用、寻址方式等核心概念。涵盖函数编写、条件跳转、内存操作及LLDB指令应用,适合初学者入门。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. iOS汇编

1.1 arm64汇编和x86汇编

  • 真机: arm64汇编
    • 寄存器
    • 指令
    • 堆栈
  • 模拟器: x86汇编

1.2 如何用汇编写一个函数?

  • 首先创建一个头文件.h和一个实现文件.s(大多数的汇编文件以.s结尾)
    在这里插入图片描述

2. 指令

2.1 mov

在这里插入图片描述

mov x0, #0x8

2.2 ret

  • 函数返回
  • lr (x30) 寄存器的值赋值给pc寄存器

2.3 add

在这里插入图片描述

_add:
mov x0, #0x1
mov x1, #0x2
add x2, x0, x1
ret

2.4 sub指令

  • sub指令的格式为:
    在这里插入图片描述
_sub:
mov x0, #0x3
mov x1, #0x2
sub x2, x0, x1
ret

2.5 cmp

  • 将2个寄存器相减
  • 相减的结果会影响cpsr寄存器的标志位
    在这里插入图片描述

_add:
mov x0, #0x3
mov x1, #0x2
cmp x0, x1
bgt mycode
mov x2, #0x5

mycode:
mov x2, #0x6

ret

2.6 跳转指令b 和 bl

在这里插入图片描述

2.6.1 b

  • 跳转指令
  • 可以带条件跳转,一般跟cmp配合使用

2.6.2 bl

  • 带返回的跳转指令
  • 执行的操作
    • 将下一条指令的地址存储到 lr (x30) 寄存器中
    • 跳转到标记处开始执行代码

2.6.3 b 和 bl 指令的区别

  • 就是b不带返回, 即使有ret 也不会返回
  • bl 会带返回, 执行完跳转指令, 立马返回到下一条指令

2.7 条件域

  • EQ: equal,相等
  • NE: not equal,不相等
  • GT: great than,大于
  • GE: greate equal, 大于等于
  • LT: less than,小于
  • LE: less equal, 小于等于
    在这里插入图片描述

2.8 内存操作

  • load, 从内存中读取数据
    • Idr、Idur(用来接收负数的)
    • ldp (p是pair的简称)
      在这里插入图片描述
; ldr指令
ldr x0, [x1]; // 从`x1`指向的地址里面取出一个 64 位大小的数存入 `x0`

; ldp 指令
ldp x1, x2, [x10, #0x10]; // 从 x10 + 0x10 指向的地址里面取出 2个 64位的数,分别存入x1, x2
  • store, 往内存中写入数据
    • str、stur(用来计算负数的)
    • stp : 从内存中读取数据, 放到一对寄存器中
      在这里插入图片描述
      在这里插入图片描述
; str指令
str x5, [sp, #24]; // 把x5的值(64位数值)存到 sp+24 指向的内存地址上

; stp 指令
stp x29, x30, [sp, #-16]!; // 把 x29, x30的值存到 sp-16的地址上. 
ldp x29, x30, [sp], #16;  // 从sp地址取出 16 byte数据,分别存入x29, x30. 然后 sp+=16;

2.9 指令列表

在这里插入图片描述
在这里插入图片描述

3. 寄存器

3.1 通用寄存器

  • 64bit的: x0~x28
  • 32bit的: w0~ w28 (属于x0 ~ x28的低32bit)
  • x0~x7通常拿来存放函数的参数,更多的参数使用堆栈来传递
  • x0通常拿来存放函数的返回值
  • 通过LLDB可以查看所有的寄存器(register)
register read

在这里插入图片描述

3.2 程序计数器

  • pc (Program Counter)
  • 记录CPU当前指令的是哪一条指令
  • 存储着当前CPU正在执行的指令的地址
  • 类似于8086汇编的ip寄存器

3.3 堆栈指针

  • sp (Stack Pointer)
  • fp (Frame Pointer) ,也就是x29

3.4 链接寄存器

  • lr (Link Register) ,也就是x30
  • 存储着函数的返回地址

3.5 程序状态寄存器

  • cpsr (Current Program Status Register)
  • spsr (Saved Program Status Register) ,异常状态下使用
    在这里插入图片描述
    在这里插入图片描述

3.6 零寄存器,里面存储的值是0

  • wzr (32bit, Word Zero Register)
  • xzr (64bit)

4. 寻址方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 总结:
[x10, #0x10]      // signed offset。 意思是从 x10 + 0x10的地址取值
[sp, #-16]!       // pre-index。  意思是从 sp-16地址取值,取值完后在把 sp-16  writeback 回 sp
[sp], #16         // post-index。 意思是从 sp 地址取值,取值完后在把 sp+16 writeback 回 sp

常用LLDB的汇编指令

  • 查看单个寄存器的值
register read x0
  • 读取所有寄存器的值
register read
  • 给某个寄存器写入值
register write 寄存器 值
  • 查看内存地址的内容
x 地址

在这里插入图片描述

  • 打印方法相关
    • po $x0 :打印方法调用者
    • x/s $x1 :打印方法名及地址
    • po $x2 :打印参数(以此类推, x3、x4也可能是参数)
    • 如果是非arm64 ,寄存器就是r0、r1、 r2

生成汇编文件

  • main.s 可写可不写, 默认生成main.s文件
xcrun --sdk iphoneos clang -S -arch arm64 main.c -o main.s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值