arm64汇编指南

寄存器

寄存器是CPU的组成成分, 存放着指令、数据和地址,速度比内存块

分为通用寄存器状态寄存器浮点寄存器

通用寄存器

ARM64有31个通用寄存器, 每个寄存器可以存储64位数据(8个字节)

使用 X0-X30 表示64位的数

使用 W0-W30 时,访问这些寄存器的低32位, 会将高32位清0。

  • X0-X7

    传递函数的参数, 如果有更多的参数需要使用栈来传递, X0 用来存储函数的返回值

  • SP(Stack Pointer)

    栈指针寄存器, 指向栈的顶部, WSP表示栈指针的最低32位

  • FP(Frame Pointer)

    即X29, 栈指针寄存器, 指向栈的底部

  • LR(Link Register)

    X30 链接寄存器, 存储着函数调用完成时的返回地址

    用来存储函数调用栈跟踪, 程序在崩溃时能够将函数调用栈打印就是借助LR寄存器来实现的

  • PC(Program Counter)

    保存下一条指令的内存地址, 通常在调试状态下看到的 PC 值都是当前断点处的地址

状态寄存器(CPSR)

保存指令运行结果的信息

根据运算的结果来设置状态寄存器的标志位

CPU内部进行置位, 不能用程序赋值

28-31位(最后四位 0011 == 6)分别代表 V C Z N

  • N(Negative)

    符号整数进行运算时, N=1表示结果为负数, N=0表示结果>=0

  • Z(Zero)

    Z=1表示运算结果为0, Z=0表示结果为非0

  • C(Carry)

    加减法运算是否产生进位

  • V(Overflow)

    加减法运算时产生符号位溢出

浮点寄存器(FPU)

用于浮点数存储和运算, V0-V31

常用指令

算法指令

  • ADD 加

    ADD X0,X1,X2: X0=X1+X2

  • SUB 减

    SUB X0,X1,X2: X0==X1-X2

  • MUL 乘

    MUL X0,X1,X2: X0=X1*X2

  • SDIV 有符号数除法运算

    SDIV X0,X1,X2: X0=X1/X2

  • UDIV 无符号

  • CMP X28,X0

    X28,X0相减,更新CPSR中条件标志位

  • CMN CMN X28,X0

    X28,X0相加,更新CPSR中条件标志位

  • ADDS/SUBS

    S的指令运算结果会影响 CPSR中的条件标志位

条件跳转

  • B.cond

    B.cond label 若cond为真,则跳转到 label

  • CBNZ

    CBNZ Xn,label 若Xn!=0,则跳转到label

  • CBZ

    CBZ Xn,label 若Xn==0, 则跳转到label

无条件跳转

  • B

    B label 无条件跳转

  • BL

    BL label 无条件跳转,返回地址保存到LR寄存器中

  • BLR

    BLR Xn 无条件跳转到Xn寄存器的地址,返回地址保存到LR寄存器中

  • BR

    BR Xn 无条件跳转到Xn寄存器的地址

  • RET

    返回到LR中存储地址

逻辑指令

  • AND

    AND X0,X1,X2: X0=X1&X2

  • EOR

    X0=X1^X2

  • ORR

    X0=X1|X2

赋值指令

MOV

MOV X19,X1 X19=X1

地址偏移

ADR

ADR Xn,label Xn=PC+label

Load/Store指令

LDR Xn,addr Load

内存地址addr -> Xn

STR Xn,addr

Xn -> 内存地址addr

LDP Xn1,Xn2,addr

内存地址addr -> Xn1和Xn2

P(Pair)表示一对,同时操作两个寄存器

STP Xn1,Xn2,addr

Xn1和Xn2 -> addr

LDUR Xn,[base, #XXX]

addr(base+#XXX) -> Xn

STUR Xn,[base, #XXX]

Xn -> base+#XXX的内存地址

扩展含义

B 无符号8bit

SB 有符号8bit

H: 无符号116bit

SH 有符号16位

W 无符号32位

SW 有符号32位

函数调用汇编

定义一个最简单的函数调用

csharp 复制代码
int addTwoValue(int a, int b) {
    return a + b;
}

int main() {
    return addTwoValue(1, 2);
}

查看汇编源码

main 函数

ini 复制代码
ZZDemo`main:
    0x1027ba1e8 <+0>:  sub    sp, sp, #0x20 ; 开辟0x30大小的栈空间
    0x1027ba1ec <+4>:  stp    x29, x30, [sp, #0x10] ;保存当前函数的x29(FP)和X30(LR)到栈中
    0x1027ba1f0 <+8>:  add    x29, sp, #0x10 ; 抬高栈底,切换到子函数栈空间
    0x1027ba1f4 <+12>: stur   wzr, [x29, #-0x4]
    0x1027ba1f8 <+16>: mov    w0, #0x1 ; 第一个参数1保存到w0
    0x1027ba1fc <+20>: mov    w1, #0x2 ; 第二个参数2保存到w1
->  0x1027ba200 <+24>: bl     0x1027ba1c8  ;调用 addTwoValue函数
    0x1027ba204 <+28>: ldp    x29, x30, [sp, #0x10] ;从栈中恢复当前函数的x29(FP)和X30(LR)
    0x1027ba208 <+32>: add    sp, sp, #0x20 ; 回收栈空间
    0x1027ba20c <+36>: ret  
csharp 复制代码
ZZDemo`addTwoValue:
    0x100c3e1a8 <+0>:  sub    sp, sp, #0x10
    0x100c3e1ac <+4>:  str    w0, [sp, #0xc]
    0x100c3e1b0 <+8>:  str    w1, [sp, #0x8]
->  0x100c3e1b4 <+12>: ldr    w8, [sp, #0xc]
    0x100c3e1b8 <+16>: ldr    w9, [sp, #0x8]
    0x100c3e1bc <+20>: add    w0, w8, w9
    0x100c3e1c0 <+24>: add    sp, sp, #0x10
    0x100c3e1c4 <+28>: ret    

一般函数执行流程如下

  1. 分配栈空间
  2. 如果有子函数调用, 保存当前函数的形参到栈中
  3. 如果有子函数调用, 保存当前函数的FP和LR
  4. 抬高栈底, 切换到子函数栈
  5. 设置子函数的实参
  6. 调用子函数,返回结果
  7. 恢复当前函数形参
  8. 恢复当前函数的FP和LR
  9. 其他操作
  10. 回收栈空间
  11. 返回

Objective-C汇编

OC中方法调用是通过消息机制来实现的

objectivec 复制代码
@implementation AppDelegate

- (void)printValue1:(NSString*)value1 value2:(NSString*)value2 {
    NSLog(@"%@, %@", value1, value2);
}

@end

int main() {
    AppDelegate *delegate = [[AppDelegate alloc] init];
    [delegate printValue1:@"111" value2:@"222"];
}

断点到函数处执行

ini 复制代码
register read

        x0 = 0x000000028261c0e0
        x1 = 0x00000001040d3109  "printValue1:value2:"
        x2 = 0x00000001040d4070  @"111"
        x3 = 0x00000001040d4090  @"222"
        x4 = 0x0000000000000004
        x5 = 0x0000000007600000
        x6 = 0x0000000000000000
        x7 = 0x0000000000000000

po $x0

<AppDelegate: 0x28261c0e0>

在 OC 中

x0 寄存器保存了对象本身

x1保存了方法名,

x2-x7保存了函数的其他参数

相关推荐
流年如夢14 小时前
类和对象(上)
android·java·开发语言
用户860225046747215 小时前
从入门到进阶的 React Native 实战指南
android·前端
沐言人生15 小时前
ReactNative 源码分析10——Native View创建流程createView
android·react native
问心无愧051315 小时前
ctf show web入门98
android·前端·笔记
李斯维15 小时前
Jetpack 生命周期组件 Lifecycle 的设计思想和使用
android·android studio·android jetpack
Mr YiRan15 小时前
Android构建优化:基于Git Diff+TaskGraph
android·git·elasticsearch
赏金术士15 小时前
第二章:Compose入门—声明式UI编程
android·ui·kotlin·compose
星间都市山脉15 小时前
Android 谷歌 VTS 完整测试
android
齊家治國平天下15 小时前
Android 14 AIDL HAL 使用指南-获取服务流程解析
android·hal·aidl·servicemanager·aidl hal·获取服务
张二娃同学16 小时前
02_C语言数据类型_整型浮点型字符型一次讲清楚
android·java·c语言